Translation Using asSam() and LINQ for Java
Ming-Yee Iu
mingyeeiu+lambda at gmail.com
Sat May 29 00:16:34 PDT 2010
> Please forgive my ignorance, but isn't LINQ a purely compile-time
> transformation?
>
> Alessio
Yes, LINQ, as implemented by Microsoft, is a purely compile-time
transformation. Although Oracle now directs Java, it will probably
take a long, long time for compiler support for database queries to be
added to Java, if ever.
So the most practical way to add support LINQ-style queries to Java
within the next 5 years would be through classloader tricks or other
bytecode rewriting techniques. Unfortunately, using asSam() for lambda
expressions causes problems for this bytecode rewriting.
These are the particular problems that I can see right now:
Consider the query
final String parameter = "UK";
Collection results = database.getAccounts().where(
#(Account a) a.getCountry().equals(parameter));
in which the where() method is declared with a signature like
<U> public ResultSet<U> where(WhereRestriction<U>)
and in which the where() method is expected to generate the database query
SELECT * FROM Accounts WHERE Country = ?
1. During bytecode analysis, it's not possible to determine which code
to analyze. When translating using inner classes, the bytecode
analyzer in the classloader can simply look for classes that implement
the WhereRestriction interface. When asSam() is used, it is hard to
determine that a particular method is intended to be used in a query
since the conversion of a method to a WhereRestriction is done at
runtime.
2. The where() method needs to crack out the query parameters from the
lambda expression that it is given. With inner classes, the query
parameters are stored as fields in the inner class, so the where()
method can use reflection or bytecode rewriting to get access to these
parameters. Using the asSam() approach, the parameters are hidden
inside some runtime-generated opaque object.
3. The where() method needs to know which lambda expression it was
given. With inner classes, the reference given to the where() method
directly correlates to the code, so the where() can do something like
public where(WhereRestriction w)
if w.class is OuterClass$InnerClass then
...
But with asSam(), there is no way for the where() method to know which
lambda expression it was given because the lambda expression has been
wrapped by a runtime-generated opaque object.
---
There are probably workarounds for these issues, but the trade-off is
much more complexity--to the point where this avenue for adding
LINQ-style queries to Java may become infeasible.
-Ming
More information about the lambda-dev
mailing list