Forgot your password?
typodupeerror
Programming

Journal: Constructors are a crude tool to set those finals

Journal by usrusr
Jonathan Locke, the Wicket guy, has a very interesting (if older) blog entry about how the old and tired way of constructor methods could be superseeded by something better.

Like a typical Locke creation, the idea immediately looks very convincing, without being wrapped in a huge bubble of buzzwords.

What i'll do no is try to break up his description/examples into maybe a little more formal pseudo-java.

The central idea is that fields should be final as often as possible and therefore the compiler should be much smarter as to how long initialization of final fields could possibly be delayed. In other words: much more fine-grained enforcement of final initialization (and toleration of lack of initialization). In current java, the rules are simple: initialize in the damn constructor or leave off that shiny final modifier. My interpretation of his examples goes like this:

Each final member would basically create a full partition of the class into two specializations, represented here as implicit interfaces:

Given the example from Jonathan Locke's blog entry
class MyClass{
final int value;
}
we would traditionally be forced to set value in each of the constructors of MyClass.

In this example, MyClass would either be "implicitly implementing" MyClass.value.new or MyClass.value.final . Each final field not initialized by traditional means would get a pair of bisecting implicit interfaces like that, so there would also be MyClass.someOtherFinalField.new, MyClass.someOtherFinalField.final and so on. Sometimes we'd know statically which of those a reference was in (e.g. after assinging a new instance) and sometimes we'd not. The original example also introduced states (like CONNECTED) syntactically separate from fields, but those are really just the same thing, just without an actual meaningful value other than uninitialized/initialized.

Each method that reads MyClass.value would only really exist on the implicit interface MyClass.value.final, while the methods that set MyClass.value would only exists on MyClass.value.new. The beauty is that there could be methods initializing or consuming arbitrary combinations of fields, whose availability would be determinded reliably and fine-grained by the availably inferred state interfaces. Since all those methods would be hidden in the basic type MyClass, none of those methods would be available if we don't know the exact implicit interfaces unless we do something equivalent of casting, which would document the possibility of a runtime exception in the code.

The part that goes beyond an implicit army of pairs of XORed interfaces on top of a little basic type inference is that, during static type checking, the inferred type of a reference changes from implements MyClass.*.new to implements MyClass.*.final whenever a method from MyClass.*.new is called.

PS: after writing this, i get the uncanny impression that by using the reserved keywords "new" and "final" in the names of the implicit interfaces (which are really about the most reasonable words i could imagine for this and not just chosen because they would be available, when i started writing this i was using .initialized and .uninitialized and it was plain ugly), it would even be possible to add this into java without the most obvious incompatibilities with existing source - i really never expected this.

The secret of success is sincerity. Once you can fake that, you've got it made. -- Jean Giraudoux

Working...