Showing posts with label irritant. Show all posts
Showing posts with label irritant. Show all posts

Friday, February 01, 2008

Today's Java Irritant: No sense of closure.

There's still enough back-and-forth about the inclusion of closures in Java 7 that I'm nervous it might not make it in to the language.

James Gosling supports the addition of closures and states that the reason they weren't there in the first place was due to time pressures and seems to have some regret about their absence (understandable; he's a Pretty Smart Dude and probably feels the pain of Java wartage more keenly than most).

Ricky Clarkson blogs about why we need a new syntactic construct to make the use of closures cleaner and less verbose, even while admitting that Java does, in fact, have a form of support for closures already.

My languages of choice (Lisp, Smalltalk, Ruby, etc.) all have cleaner support for closures without the syntactic overhead that current Java has. For a trivial example we can compare the use of closures for processing a file.

file.each_line do |line|
# Process line of file.
end

With current Java syntax we might end up with something like this:

import static bar.baz.eachLine;
...
eachLine(file, new EachLine() {
void doLine(String line) {
// Process line of file.
}
});

We could also create a File-like object with an eachLine method.

This isn't the Worst Syntax in the World, but it still makes me think more when writing the code and when I'm reading it later.

A relatively minor point is that any variable used in the closure must be declared as final in the enclosing method. This may obfuscate the actual functionality of the enclosing method and, in some cases, require the introduction of a final variable just to satisfy the requirements of Java's current "closure" syntax/implementation.

It'll be interesting to see what finally happens; I hope that (a) support for closures is added and (b) it doesn't irritate me too much.

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).

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.