Monday, December 31, 2007

Today's Java Irritant: Design-by-Contract Disconnects.

Design-by-contract systems enforce API behavior. In Eiffel, contracts specify both internal and external behavior, at the language level.
connect_to_server (server: SOCKET)
require
server /= Void and then server.address /= Void
-- etc.
end

This does what it looks like, at runtime. (/= == != :)

The cost of doing the same in Java is higher; most frameworks use some form of aspect-oriented programming. This isn't a bad thing in itself, but gives some people (managerial types and unimaginative programmers) the heebie-jeebies. Dealing with issues created by lots of aspects can be daunting, but are relatively straight-forward in a well-educated Java house.

Lighter-weight solutions exist, may be preferable in many situations, and are easy to grok. Putting a chunk of precondition tests at the start of a method is trivial:
public String foo(final String bar_) {
Pre.notBlank(bar_);
// etc...
}
Here, the issue is that there's no automagic way to track or document preconditions other than either manually documenting them in Javadocs (preferably through a simple doclet tag, like @pre, or whatever) , or by programmatically scanning the source and pulling out "useful" information and doing something useful with it. Neither are particularly appealing: Javadocs go stale quickly, and writing a robust source parser is non-trivial.

Another answer is to use one of the annotation- and/or aspect-based solutions (or XDoclets, but... ew?) and swallow the bitter pill that is Java, and pay the cost of educating your developers. The packages I'm currently considering are Contract4J, which uses pre-built AspectJ aspects, and SpringContracts (which is nice since most my projects use Spring).

Wednesday, December 19, 2007

OLPC: Minimal First Impressions

Hooray, my OLPC arrived this morning!

Without having the time to go in to any detail, here some initial first impressions.

- It's really small, but the carrying handle and LCD hinge/swivel assembly make it larger than my Eee PC. Not a huge issue for me, and the hinge/swivel makes for some cool functionality that I want in a small notebook. Handle I can live without, but it won't be a deciding factor for me. Tie.

- It's marginally heavier than the Asus. Subjectively I prefer holding the Asus in one hand; the weight distribution seems better/more convenient. Winner: Asus. UPDATE: I just found a nice way to hold the OLPC; if you wrap your arm around it you can rest the back end on your forearm while the front rests on your chest. It's a little awkward, but the additional depth makes it a bit more convenient than the Asus (I think). NEW WINNER: Tie.

- You've seen the keyboard, you don't need me to add anything, right? Fine. The Asus keyboard is obviously better for most of what I need to do. That said, I'd be more comfortable taking the OLPC into harsher environments, which I need on occasion. Winner: Asus, with caveats that make it seem more like a tie.

- Boot-up time is acceptable, but slower than the Asus. Again, this won't be a major deciding factor, but a quick boot-up is rather important to me: the quicker it starts up, the quicker I can do something useful, the more likely I'll be to make use of the functionality I can hold in my hand. Asus (20-25 seconds worst case), OLPC (90+seconds?!). Winner: Asus, hands-down.

- The OLPC screen is pretty nice, and the no-backlight mode is really easy to read in bright light, and passable in low-light. The Asus screen is good too, but (so far, anyway) I haven't been able to turn the backlight off. Winner: OLPC.

- Apps: The Asus is a typical Linux box. The OLPC as delivered isn't set up for non-kid use, but there's a shell available, vi is installed by default, and I'm assuming I'll be able to use it as a generic Unix box w/o much of a hassle. I could be wrong. As delivered, winner: Asus. In reality, most likely dead even.

- Speed: Asus, no contest, at least so far. The OLPC is running a Geode at 433MHz, the Asus a Celeron M (at 630MHz?). I'm surprised the perceived speed difference is so great, and I'm not sure where the biggest differences are. Hopefully someone with more time will post some I/O benchmarks.

- Battery life: Don't know yet. I'm guessing the OLPC, perhaps even by a landslide. The Asus will go ~3 hrs, depending on what you're doing. I'd rather it was... a full day :)

- Noise: OLPC, hands down. The Asus gets pretty hot and has a fan and isn't afraid to use it.

- Networking: So far, I can't get the OLPC to connect to my WPA-PSK wireless; this is a MAJOR lose. I'm sure somebody else has this figured out, though. Temporary winner: Asus. UPDATE: Heng's comment does, indeed, solve the problem. New winner: Tie.

First Final Verdict: if only they could combine the two... I may end up going to dynamism.com and getting a UMPC at this rate, but they cost 2-10x as much, so I'm in no hurry. I suspect I'll be using the Asus more because of the keyboard, but once I have time to start hacking on the OLPC (and mod the case) that might change.

I'm excited by both, which is an unfortunate commentary on my life. This *is* a useful form factor (at least for me, and, I suspect, a lot of other people) but I'm not sure the optimal ergonomics have been figured out yet, and, as usual, we still need better batteries.

Thursday, November 29, 2007

Asus Eee PC: First Impressions

Good heavens, it's small, and I got the one with the whiny fan.

The screen, while low on density, is easily readable indoors, and adequate for my needs. The LED backlight is adjustable via Fn-F3/Fn-F4. It goes to sleep via Fn-F1 in about 3 seconds and comes back with the power switch in about 5 seconds.

Typing is... challenging, although I suspect I'll adapt with a few days use... So far the only stumpers have been the right-hand shift key (it's small, and I often hit the up-arrow by mistake), the number keys, which are shifted a half-key or so to the left, and re-training the fingers to not track as far--the keys are quite close together.

Ctrl-Alt-T brings up xterm; I replaced that by editing my ~/.icewm/keys file to use konsole:
key "Ctrl-Alt-t" konsole

Setting up virtual desktops was also straight-forward; I edited ~/.icewm/preferences to include them, and a start menu:
TaskBarShowStartMenu=1
ShowProgramsMenu=1
TaskBarShowWorkspaces=1
WorkspaceNames="1", "2"

Putting the unit to sleep seems to mess up wireless connections; it's irritating--hopefully I'll figure out why that's happening so I don't have to keep typing in my ridiculous wireless password (it supports WPA, which is handy).

A real desktop can be had by installing kicker:
apt-get install kicker
apt-get install ksmserver

I had some issues with the task bar in full desktop mode that haven't been resolved yet; it redraws incorrectly when there's more tasks than taskbar. I may actually stick to "simple" mode for the time being.

While some have panned OpenOffice.org's performance, it's not that bad. I probably won't use it very often, but it's nice to know it's there. AbiWord is another option. VIM comes pre-installed... while I'm an Emacs person, I'm a little scared to even try it (I dread an even more-cramped Emacs claw), so I'll probably stick with something else on the little guy.

When my OLPC arrives I'll be comparing the two to see which will be my "drag it around" machine--the Asus is light but I suspect not as robust as the OLPC, and I really like the OLPC's screen.

For now the Asus will serve as a note-taking little-bits-of-work machine used during commutes. Battery life will be an issue; my MacBook Pro 17" Hi-Res will go round-trip w/o recharging, about 2.5-3 hrs, doing word processing and Java web development. The Asus is claimed to last 3.5 hrs and I doubt I'll be doing any Java development on it, but I may be able to continue using OOo for some books-in-progress.

It will also make an interesting hackery platform.

Monday, November 26, 2007

Today's Java Irritant: Java's Impoverished Mixology

Today's Java Irritant is the lack of mixins or similar functionality, although Warth et al.: Expanders have an implementation.

A current project has an interface consisting of about two dozen getters (and setters). This interface is implemented by a minimum of two classes due to design and lack of multiple inheritance.

Being forced to implement this functionality in even one place, not tucked away in some base class, module, mixin, etc. is irritating enough: having it in two places is more than twice as bad. Keeping the implementations in sync is irritating. Looking at the code so I know I can ignore it is irritating. Maintaining three sets of code (the interface and two classes) is irritating.

This functionality is available for Java--sort of. Warth et al. created Expanders via the Polyglot compiler front end. It allows classes to be non-invasively updated with new methods, fields, and superinterfaces.

Expanders look like what we want, and like the rest of Java, are statically-typed, preventing at least some types of errors.
package some.pkg;

public class SomeJavaClass {
// Normal class definition.
}

...

package interfaces;

public expander Foo of SomeJavaClass {

private String _someProp;

public void setSomeProp(final String someProp_) {
_someProp = someProp_;
}

public String getSomeProp() {
return _someProp;
}
}

...

import some.pkg;
use interfaces.Foo;

public class UseThatShiznit {

public static void main(final String[] args) {
SomeJavaClass anInstance = new SomeJavaClass();
anInstance.setSomeProperty("No brainer.");
}

}

This is a crude use of Expanders. Consider the creation of a Swing JTree-aware class via Expanders: rather than include Swing-specific information in the class itself we can create an Expander that implements TreeNode and ILabelProvider and since Expanders are typed, we can create different expanders for different classes. If there is shared behaviors, no worries; Expander behavior can be overridden just like class behavior.
use StringIconExp;
public expander PublicationExp of Publication implements TreeNode, ILabelProvider {
// Enumeration children()...
// String getText()...
public Icon getIcon() {
return "/icons/publication.gif".getIcon();
}
}

What's that getIcon() code doing?! Strings don't have a getIcon() method... but strings with an expander do.
public expander StringIconExp of String {
private Icon icon = null;
public Icon getIcon() {
if (icon == null)
icon = new ImageIcon(Object.class.getResource(this));
return icon;
}
}

Yes, this could be implemented with source generation tools, but that's a poor substitute for type-safe, naturally-composable functionality in the language itself, and it adds a layer of build-time complexity that must be documented and maintained.

If you think GroovyScala, and so on are tough sells, try selling Expanders. It's tantalizing, but experimental, and with the current crop of JVM languages, I doubt we'll be seeing it in mainline Java.