Thank you…

…to whoever at Sun decided it would be a good idea for java.awt.geom.Point2D and java.awt.Point to override equals() and hashCode() even though they’re mutable. That’s four hours of my life I’m never going to get back.

Fun, or rather no fun, with generics (updated)

So, I understand that the following doesn’t work, but why doesn’t it work?

interface Adapter {}

class Adaptulator<I> {
    <e, A extends I & Adapter> void add(Class extl, Class<A> intl) {
    	addAdapterFactory(new AdapterFactory(extl, intl));
    }
}

The add() method gives me a compile error, “Cannot specify any additional bound Adapter when first bound is a type parameter” (in Eclipse), or “Type parameter cannot be followed by other bounds” (in IDEA), take your pick.

Clearly you’re just Not Allowed to use the type parameter I there, before the &, and that’s that. (And before you ask, it doesn’t work if you switch ’em, because there’s no guarantee that I isn’t a concrete class.) But why not? I’ve looked through Angelika Langer’s FAQ and can’t find an answer.

Generally when some generics limitation seems arbitrary, it’s because you’ve created a situation where the type system can’t actually enforce correctness. But I don’t see what case would break what I’m trying to do here. I’d say maybe it has something to do with method dispatch after type erasure, but there’s only one add() method, so it’s not like there’s any ambiguity…

So what’s the problem?


Update: I cross-posted this to stackoverflow.com, and Bruno De Fraine pointed out that the reason multiple bounds were introduced in the first place was to control the erasure. Since I is just going to erase to Object, it doesn’t get you anything there. Unfortunately, all I wanted was the compile-time type safety, so I’ll have to come up with something else…

Closures now please

I’m trying to fix the event handling in some table code someone else wrote a few months back (where “fix” here means “support an ugly legacy global event model without just calling fireTableDataChanged() for every little thing”). I pretty much know what I need it to do, but setting up the test expectations is seriously painful. Among other things, I’m having to crawl the table model to build up “expected” sets of rows and columns for each event, over and over again, with a slightly different crawl condition for each test.

Closures would make this clean, or at least easy. But we don’t have them, so instead it’s:

	private static interface ColMatcher {
		boolean matches(TableColumn col, int index);
	}

	private Set findColumns(ColMatcher matcher) {
		Set expectedCols = new HashSet();
		for (int col = 0, numCols = tableModel.getColumnCount(); col < numCols; col++) {
			TableColumn column = tableModel.getColumn(col);
			if (matcher.matches(column, col)) {
				expectedCols.add(col);
			}
		}
		return Collections.unmodifiableSet(expectedCols);
	}

and then, over and over again:

	public void testSomeLegacyEvent() {
		final Set expectedRows = ...;
		final Set expectedCols = findColumns(new ColMatcher() {
			@Override public boolean matches(TableColumn column, int index) {
				return /* some condition */;
			}
		});

		final NastyLegacyEvent e = ...;

		SwingUtilities.invokeAndWait(new Runnable() {
			@Override public void run() {
				nastyLegacyEventSystem.fireLegacyEvent(e);

				Set affectedColumns = tmListener.getAffectedColumns();
				assertEquals(expectedCols, affectedColumns);
				for (int col : expectedCols) {
					assertEquals(expectedRows, tmListener.getAffectedRows(col));
				}
			}
		});
	}

There’s really got to be a better way

His code not ‘functional’ or ‘elegant’

In the middle of another gold card, this one on Actors (PDF), a concurrent programming abstraction that Scala borrowed from Erlang. The Scala short tutorial on actors isn’t much help, at least not to someone who’s spent as little time with Scala as I have; mostly Mr. Haller just seems to show you the source code from the examples directory and say “see”? But I persevere.

In the course of said perseverance, I did run across one interesting link, which I post by way of bookmarking: Functional Java, “an open source library that aims to prepare the Java programming language for the inclusion of closures [and] serves as a platform for learning functional programming concepts by introducing these concepts using a familiar language.” Which sounds like exactly what Code Monkey needs.

Substantial forms of being

So I gave my pizza lunch talk on monads today, having over the past couple of weeks snuck in considerably more than a single Gold Card day’s worth of work. I think it went fairly well and was mostly comprehensible, though on the comprehensibility front it probably helped that a lot of my statements were wrapped in “I’m not sure what…”, “I’m not sure whether…” and “I’m not sure why…” —

— which, if you think about it, is really just a kind of Option (a.k.a. Maybe), so it’s totally appropriate.

At least, that’s (provisionally) my story and I’m (for now) sticking to it.

I got as far (I think) as figuring out what a monad is (mostly), and (I think) how the Scala List and Option monads work (mostly), largely by porting (partially) List and Option to Java. I mean to turn the talk into a post here, but that’ll take a couple of days — maybe longer if I get ambitious about cleaning up the code examples.

What I didn’t get to in any detail was Dan’s question about state, which was sort of the main point of this investigation, along with I/O and error handling. Always leave yourself some work for tomorrow, I’ve been told….

Unit, bind, flatten

I’m 3/4 of the way through my Gold Card day, and I think I can finally tell a monad from a modron, and even from a maenad. Whether this will translate into a presentation anyone else can understand is still an open question.

Meanwhile, I’ve discovered:

  • A whole folder of monad examples in the Scala distribution.
  • That trying to do higher-order functional programming in straight Java does, in fact, really blow. An example that takes 74 lines in Scala takes… well, I don’t really know how many lines it takes in straight Java, because nine classes and 195 lines in, I’m only up to line 37 in the original (single) Scala file. We could extrapolate and guess 390 lines, but I wouldn’t bet on it. Maybe those BGGA closures aren’t such a bad idea after all…
  • James Iry’s “Monads are Elephants,” an introduction to Scala monads that’s got more words and less math than Burak Emir‘s. (Nothing against math — or Dr. Emir — but we language majors like our human-readable variable and function names.)
  • Scala for Java Refugees,” a nice tutorial from Daniel Spiewak.

And, last but not least:

  • That “Introductions to monads are bit of cottage industry on the Internet.” (James Iry again.)

So much for my plan to get rich writing Monads for Dummies.

Java vs. C#: More fun with initializers

Or, proof by example that C# isn’t just Java with different capitalization conventions.

On the heels of Neal Gafter’s ice cream puzzler we have the less closure-rific but still interesting “Why do initializers run in the opposite order as constructors?” from Eric Lippert. Here’s my Java version of Eric’s C# code:

class Foo {
	public Foo(String s) {
		System.out.printf("Foo constructor: %1$sn", s);
	}
}

class Base {
	private final Foo baseFoo = new Foo("Base initializer");

	public Base() {
		System.out.println("Base constructor");
	}
}

class Derived extends Base {
	private final Foo derivedFoo = new Foo("Derived initializer");

	public Derived() {
		System.out.println("Derived constructor");
	}
}

class Program {
	public static void main(String[] args) {
		new Derived();
	}
}

I’ll spare you the suspense and just print the answer — the Java answer, that is.

Foo constructor: Base initializer
Base constructor
Foo constructor: Derived initializer
Derived constructor

Whereas the C# code equivalent of the above, Eric’s original, prints:

Foo constructor: Derived initializer
Foo constructor: Base initializer
Base constructor
Derived constructor

What’s going on?

The Java code does this because when a Java object’s initialized the JVM works its way down through its superclasses, starting at the root (that is, Object), and for each class first runs the initializers, then the constructor. This can have some wacky side-effects. For instance, sooner or later everyone gets the bright idea to define an abstract method in the base class and call that method from the base class constructor — which works fine until some subclass’s concrete implementation depends on a field that’s only initialized in that subclass, and suddenly you’re getting NullPointerExceptions in impossible-looking places.

This happens whether the field’s initialized in the subclass constructor or in a subclass initializer, and while it’s fairly obvious what’s going on in the constructor case, it’s a little more confusing the first time you have, say,

private final long timestamp = new Date().getTime()

come out 0 (or null, if you use a capital-L Long) when you know your clock’s not set to January 1st 1970 — and then later on come out 1203338390828 or whatever, even though final fields are supposed to be immutable.

The constructor case, I think we’re stuck with. The initializer case, though, the folks at Microsoft apparently decided they were sick of. So C# instead runs all the initializers in reverse order (subclass to superclass), and then runs all the constructors (in the order you’d expect). This means final fields in C# really are final, or rather, readonly fields really are read-only — they’ll only ever have one value, no matter when you look at them. [Looks like I didn’t have that quite right — see Eric’s comment below.]

Now I wonder what happens in ActionScript? The Adobe folks claim my const bug in FlexBuilder is fixed; I’ll have to download the latest build and see.

Comments closed due to spam.