hg: lambda/lambda/langtools: Added basic support for constructor references.
Thomas Münz, XDEV Software Corp.
t.muenz at xdev-software.de
Tue Jan 18 00:16:07 PST 2011
Although I must confess I don't fully understand what the bottom line of your text is supposed to be (just Field references were not in the scope of project lambda? Field references are bad per se? Only the "#" can't be used for Field references and apart from that everything is fine for the future?), I want to add the following from an ordinary java developer's view:
It is fully understandable that Field references (weren't they called "Field literals" once? Or is that another thing?) are not in the scope of project lambda.
Still, this shouldn't mean that there is no need for a future feature like that just because they're not closely related to lambdas (it sounded that way, sry if that's a misinterpretation).
I once read in a proposal for adding Field and Method literals: "While this proposal would certainly address a pain-point when using reflective frameworks, I don't think it would directly benefit the masses of Java programmers" [1].
I don't think this is right and I think that field and method references are badly needed (not now, no problem, but sometime in the future) and that they should at least be kept in mind when designing other language extensions.
The reason why they are badly needed are frameworks that have to generically handle classes, like OR-Mappers (or imagine a generic Class-To-GUI-Components Mapper, etc.).
Those all have to use java.lang.reflect Field to achieve that level of genericity. To programmatically influence or configure them (like excluding certain fields in certain runtime cases, e.g. lazy loading etc., process only specifiy fields, etc.), one must pass Field instances. Currently, to do so, you have to pass strings as a workaround (which is an architectural nightmare) or have to abuse annotations as a workaround.
The same surely applies to java.lang.reflect.Method (e.g. mapping of Getters, Setters oder some RMI-like frameworks, etc.).
In my experience, if you want to design properly abstracted frameworks that generically map classes to anywhere, you always end up using reflection, demanding reflect-Types as a consequence for full usablity. That those reflect-types aren't used as much today (well, I do :-D) is more like a symptom of the missing syntax than a reason not to retrofit it.
Also, if such literals will be introduced in the future but will use something different than java.lang.reflect.Field (like that Property) it will help almost nothing, because frameworks already use (and expect in their interfaces) Field. Same for Methods, of course. I don't want to argue against MethodHandle (I think I understood the need, but I'm not completely sure as I'm no language expert :) ), I just want to say that at one point in the future, there have to be java.lang.Method references (or literals) as well (and that should by all means NOT be something like MyClass#myMethod.getReflectMethod() ).
Personally, I think for consistency with JavaDoc, the "#" should be used for java.lang.reflect.Field and java.lang.reflect.Method (btw. can't it be used in parallel, distinguished by the compiler depending on context?), but in the end, I don't care much if it will be "#" or ":" or ">" or whatever. I only know that those missing literals are a "hole" in the language, are badly needed to accomplish flexible generic frameworks and should even today be kept in mind as a much-more-needed-than-expected feature for a future language extension.
[1] http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000880.html
Subject: hg: lambda/lambda/langtools: Added basic support for constructor references. (Mon Jan 17 11:29:09 PST 2011)
From: Brian Goetz <brian.goetz at oracle.com>
> That is the most likely suspect. Which would then want that the type of
> a method reference be jlr.Method, which is problematic because Lambda
> wants method references to be SAM-converted (just as lambda expressions
> are.) At which point I say "ugh, how did we get here?" and start
> looking for backtrack paths.
>
> <observation>
> Jumping up a level, this illustrates the dark side of the (almost always
> specious) "consistency" argument**, which in this case goes like:
>
> - If you have method references, you should have field references, for
> consistency
> - The obvious type of a field reference is jlr.Field
> - Therefore for consistency, the type of a method reference should be
> jlr.Method
> - We want method references to be SAM-convertible, just like lambdas
> - Since the type of a method reference is jlr.Method, I guess we need
> a conversion from jlr.Method to SAM
> - There have been other requested conversions, e.g.,
> lambda-to-MethodHandle. So for consistency I guess we want a conversion
> from jlr.Method to MethodHandle too? And back?
> - Cycles in conversions are great feeding grounds for puzzlers.
>
> You see where this goes. You start pulling on a string, and before you
> know it you have reduced your sweater to a messy lump of string.
>
> **This is not to say that consistency is not good, but the reality is
> that the language is already full of inconsistency and therefore
> consistency can't actually be achieved, and all we can do is choose
> where we want our inconsistencies. But we can justify nearly any
> feature we happen to want by saying "for consistency!", because you can
> usually find some other feature with which it is consistent. And
> therefore it is a very weak argument (on its own) for including a
> language feature.
> </observation>
>
> Which brings me back to the original discussion: method references are
> useful for lambda. Field references, on the other hand, have very
> little contribution to lambda, and also have the major defect that they
> are really a completely different beast from method references, and
> therefore the implicit "member reference" concept (which seems like an
> obvious unifying abstraction) turns out to be a false abstraction.
More information about the lambda-dev
mailing list