Static typing for warp-widgets
08Jun08
I have been thinking about this for awhile, currently warp-widgets templates are duck typed. I want to make them statically typed (as crazybob encouraged me to). There are two parts to this.
Part #1
I had intended the widget annotations to be java annotations, which can be used to configure user-widgets dynamically…in the template:
@My(name="Jeff") <div>... </div>
…and in the class:
@EmbedAs(My.class)
public class MyWidget {
@Inject
public MyWidget(My my) {
assert "Jeff".equals(my.name()); //true
}
}
This part is fairly simple.
Part #2
The second part is making expressions statically typed, which is a bit harder. Right now we use MVEL as the expression evaluator, so:
${message}
…reads a property from getMessage(). But this is duck typed, meaning the class owning getMessage() can be anything. And because MVEL is dynamically typed, we cannot tell if the expression is wrong (i.e. does property “message” exist?) until it dies gloriously at runtime.
What are our options so that we can gain static typing guarantees? I can think of:
- writing a specialized statically typed expression language for warp-widgets (would be nice to avoid this!)
- check that the properties/paths exist on classes at template compile time (static duck typing)
- another, harder, option is to perform expression egress type narrowing at template compile time. Which will give us ‘effectively static’ typing (but under the hood we allow MVEL to evaluate the expressions, dynamically)
I can’t seem to find an easily embedded expression language for Java. The ones that do have some static typing (MVEL), use type annotations which are clunky and easy to subvert.
Any thoughts or ideas? Throw them at me: dhanji at gmail com or twitter.com/dhanji
Filed under: 1 | 2 Comments
Tags: guice, java, type system, type theory
You’re actually not correct. Strict typing in MVEL does not require explicit type qualification.
As long as you can inform the compiler of the known types of elements, everything is happy, and duck typing is pefectly acceptable in MVEL without qualification.
Drools uses MVEL in this way. Basically, you inject all the known types for injected variables into the ParserContext:
ParserContext ctx = new ParserContext();
// enable strict typing
ctx.setStrictTypeEnforcement(true);
// tell the compiler the types of ‘foo’ and ‘bar’
ctx.addInput(“foo”, Foo.class);
ctx.addInput(“bar”, Bar.class);
// compile the expression
Serializable compiledEx = new ExpressionCompiler(“foo.callFooMethod(); bar.callBarMethod()”).compile(ctx);
…
Boom, you can get compile-time warnings if you bootstrap the MVEL compiler in your tooling.
Email me anytime at mbrock@codehaus.org . I’m more than happy to help people.
I realize a lot of these nitty-gritty things are not documented, but I am working on it.