August 22, 2007

Helping javac infer generic return types

One of my pet peeves with Java generics is that you can't pass the result of a method that returns a generic type whose bounds cannot be inferred from actual arguments directly to another method. This is particularly useful when passing an empty list obtained from Collections.emptyList() to a method:

class Test
   static void foo(List<String> list) {}

   public static void main(String[] args)
     foo(Collections.emptyList()); // doesn't compile

Unfortunately, that doesn't compile. It can be worked around by doing:

List<String> list = Collections.emptyList();

It beats me why the compiler cannot infer the appropriate type for the list returned by Collections.emptyList() in the first example above. I understand why it would fail when 'foo' has multiple overloads, but it should work for the simple case when the method resolution is unambiguous.

I recently came across an obscure (yes, ugly and unintuitive) way of getting the first example to work. It consists in telling the compiler explicitly what to bind the return type to. This is the BNF definition, per the JLS 3.0:

   MethodName ( ArgumentList? )
   Primary . NonWildTypeArguments? Identifier ( ArgumentList? )
   super . NonWildTypeArgumentsopt Identifier ( ArgumentList? )
   ClassName . super . NonWildTypeArguments? Identifier ( ArgumentList? )
   TypeName . NonWildTypeArguments Identifier ( ArgumentList? )

And here's a concrete example:


Labels: ,

February 25, 2007


Design by Contract for Ruby is now a Rubyforge project. Version 1.0.0 is available as a gem:

gem install rubydbc


November 07, 2006

Extensible mod_rewrite with Lua

I was running an experiment with apache + mod_rewrite that required rules that cannot be expressed with regular expressions. mod_rewrite has the notion of rewrite maps, which let you choose from a couple of built in functions (int:tolower, int:toupper, etc.) or a key-value pair map backed by a text or dbm file.

Unfortunately, there's no way to plug in arbitrary mapping functions*, so my first thought was to extend mod_rewrite by adding a new built in function. This lets me write:

LoadModule rewrite_module modules/
RewriteEngine on
RewriteMap foo int:foo

RewriteRule (.*) ${foo:$1} [L]

It works great, but this approach requires forking mod_rewrite.c, which is obviously not a good thing.

Inspired by Brian's mod_wombat, which allows you write http handlers in Lua, I thought "wouldn't it be nice to be able to extend mod_rewrite with custom Lua scripts?". Say, something like:

LoadModule rewrite_module modules/
RewriteEngine on
RewriteMap foo lua:/usr/local/apache2/rewrite-rules.lua

RewriteRule (.*) ${foo:$1} [L]

30 lines of code later, my lua-enabled mod_rewrite prototype is able to do exactly that. Mind you, this is a very crude implementation and doesn't check for errors, cache compiled scripts, etc. But all those details can be improved.

Anyway, this is all becomes somewhat irrelevant with the latest version of mod_wombat, which allows you to define transform_name hooks in Lua, as well.

It was a interesting experiment, nonetheless :)

* To be fair, there is actually a way to do this, but I consider it to be too clunky and non-scalable to be of any value in a real production system. The mechanism consists on mod_rewrite talking to an external process that does translations via its stdin/stdout streams. As a result, a global mutex is required to guarantee correctness in the face of multiple simultaneous requests.