Field and Method Literals
Matthew Adams
matthew at matthewadams.me
Tue Nov 22 10:18:06 PST 2011
Ok, I didn't mean to start a whole crapstorm by asking.
My only concern was that one of Brian's examples at Devoxx used a "::"
operator with a lone symbol (I can't find the slide deck I saw right
now, but a verison of it is available at
http://www.parleys.com/#st=5&id=2170&sl=29):
Person::getLastName
This one is probably not such a great example to illustrate my point,
as I think no one is going to name a field "getLastName". This one is
more reasonable (albeit still contrived):
public class MyClosable { private boolean closed; public boolean closed();}
If I use the expressionMyClosable::closed
to which member am I referring? With only method literal support in
the language, then it's obviously the method, but with a full-blown
reflection literal syntax, it would be ambiguous.
All I'm saying is that the choice of method literal syntax should not
make a future reflection literal syntax different.
-matthew
On Mon, Nov 21, 2011 at 6:03 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> My bad. Next time I'll just not say anything.
>
> On 11/21/2011 6:47 PM, Neal Gafter wrote:
>>
>> Brian-
>>
>> I think we'd all feel more comfortable if we could review for ourselves
>> /how /the issues have been considered by the expert group. Oracle long
>> ago promised to provide a public mailing list where subscribers could
>> see the expert groups deliberations. Hearing your periodic assurances
>> that the expert group is on top of things doesn't really serve the same
>> purpose.
>>
>> Cheers,
>> Neal
>>
>> On Mon, Nov 21, 2011 at 2:35 PM, Brian Goetz <brian.goetz at oracle.com
>> <mailto:brian.goetz at oracle.com>> wrote:
>>
>> You "caution the expert group to carefully consider the syntax",
>> because
>> of possible ambiguities between features that are currently on the
>> requirements list (method refs) and features that are on various
>> people's wish list but not under active development (field refs).
>>
>> I was merely saying we're well aware of these issues, so you can sleep
>> well knowing that they've already occurred to us and have been part of
>> the discussion, and that while field refs are not on our requirements
>> list, we realize that it would be stupid to inadvertently close the
>> door
>> on them, and therefore have to be included in our analysis.
>>
>>
>>
>> On 11/21/2011 4:59 PM, Matthew Adams wrote:
>> > I'm not quite sure what that means. Can you please elaborate?
>> >
>> > On Mon, Nov 21, 2011 at 11:39 AM, Brian Goetz
>> <brian.goetz at oracle.com <mailto:brian.goetz at oracle.com>
>> > <mailto:brian.goetz at oracle.com <mailto:brian.goetz at oracle.com>>>
>> wrote:
>> >
>> > Don't worry, this road is already well explored.
>> >
>> >
>> > On 11/21/2011 10:34 AM, Matthew Adams wrote:
>> >
>> > I reiterate Chris's suggestion for method and field
>> literals,
>> > and caution
>> > Project Lambda to carefully consider the syntax. There is
>> an
>> > ambiguity
>> > that I want to make sure that we're not overlooking here
>> that
>> > would cause
>> > problems with various proposed method/field literal
>> syntaxes.
>> >
>> > Currently, Chris's examples and Project Lambda's "::" method
>> > reference
>> > syntax introduce an ambiguity when referring to a method
>> that
>> > has the same
>> > name as a field. See my post on this at
>> >
>>
>> http://mail.openjdk.java.net/__pipermail/jdk8-dev/2011-__November/000293.html
>> >
>>
>> <http://mail.openjdk.java.net/pipermail/jdk8-dev/2011-November/000293.html>
>> > for
>> > more detail on my suggestion. In short, though, here's
>> the jist
>> > (I'll use
>> > "::", but I still prefer "#" as the method/field literal operator).
>> > Consider the following class:
>> >
>> > public class Foo {
>> > private boolean close;
>> > @Goo(hoo="loo") public Foo() { /* ... */ }
>> > /* A */ public void close() { /* ... */ }
>> > /* B */ public void close(int timeout) { /* ... */ }
>> > }
>> >
>> > If member literal syntax is to be supported now or in the
>> future,
>> > "Foo::close" is ambiguous. What should the compiler do here?
>> > Interpret
>> > the expression as a field or method reference if it's not
>> > ambiguous? I
>> > think I'd prefer a syntax that requires parens for method
>> > references:
>> >
>> > Foo::close // field
>> > Foo::close() // refers to method A above
>> > Foo::close(int) // refers to method B above
>> >
>> > This also allows me to refer to constructors, BTW:
>> >
>> > Foo::()
>> >
>> > And annotations:
>> >
>> > Foo::()@Goo
>> >
>> > And annotation properties:
>> >
>> > Foo::()@Goo(hoo)
>> >
>> > I reiterate also that the persistence specifications JDO&
>> JPA
>> > can benefit
>> > from such constructor, method& field literals. In their
>> > absence, projects
>> >
>> > like QueryDsl, Hibernate's Criteria, JPA's Criteria, and
>> JDO's
>> > proposed
>> > typesafe query APIs have been created, using generated
>> classes
>> > to provide
>> > the typesafe references that are needed.
>> >
>> > -matthew
>> >
>> >
>> > On Mon, Apr 18, 2011 at 3:40 AM, Chris
>> Beams<cbeams at vmware.com <mailto:cbeams at vmware.com>
>> > <mailto:cbeams at vmware.com <mailto:cbeams at vmware.com>>> wrote:
>> >
>> > On Sun, Apr 17, 2011 at 8:14 PM, Collin
>> Fagan<collin.fagan
>> > at gmail.com <http://gmail.com> <http://gmail.com>>
>> wrote:
>> >
>> > But more to the point what is Chris actually asking
>> for? Is
>> > it just to be able to use static method references with
>> > annotations?
>> >
>> >
>> > This thread originated on coin-dev (thanks Rémi for
>> > cross-posting here),
>> > but I believe my original use case didn't make it
>> over. Let
>> > me reiterate
>> > and expand.
>> >
>> > Many will associate Spring with XML-based application
>> > configuration, but
>> > since Spring 3.0 we also offer a 100% Java-based
>> solution
>> > for configuring
>> > dependency injection, application of advice, and the
>> myriad
>> > other services
>> > and features of the Spring container. The central
>> artifacts
>> > in this
>> > support are user-defined "@Configuration classes". A
>> brief
>> > but practical
>> > example follows to provide context for our use cases.
>> >
>> > package com.myco.app.config;
>> >
>> > import
>> org.springframework.context.__annotation.Configuration;
>> > import org.springframework.context.__annotation.Bean;
>> > import
>> >
>>
>> org.springframework.jdbc.__datasource.embedded.__EmbeddedDatabaseBuilder;
>> > import
>> >
>> org.springframework.jdbc.__datasource.embedded.__EmbeddedDatabaseType;
>> > import
>> >
>>
>> org.springframework.orm.__hibernate3.annotation.__AnnotationSessionFactoryBuilde__r;
>> >
>> > import org.hibernate.SessionFactory;
>> >
>> > import javax.sql.DataSource;
>> >
>> > import com.myco.app.domain.Foo;
>> > import com.myco.app.service.__FooService;
>> > import com.myco.app.service.__SimpleFooService;
>> > import com.myco.app.data.__FooRepository;
>> > import com.myco.app.data.__HibernateFooRepository;
>> >
>> > @Configuration
>> > public class MyApplicationConfig {
>> >
>> > @Bean
>> > public FooService fooService() {
>> > return new SimpleFooService(__fooRepository());
>> > }
>> >
>> > @Bean
>> > public FooRepsitory fooRepository() {
>> > return new
>> HibernateFooRepository(__sessionFactory());
>> > }
>> >
>> > @Bean
>> > public SessionFactory sessionFactory() {
>> > return new AnnotationSessionFactoryBuilde__r()
>> > .setDataSource(dataSource())
>> > .setSchemaUpdate(true)
>> > .setAnnotatedClasses(Foo.__class)
>> > .buildSessionFactory();
>> > }
>> >
>> > @Bean
>> > public DataSource dataSource() {
>> > return new EmbeddedDatabaseBuilder()
>> > .setType(EmbeddedDatabaseType.__HSQL)
>> > .build();
>> > }
>> >
>> > }
>> >
>> >
>> > Such a @Configuration class may then used to
>> bootstrap the
>> > application.
>> > If we're dealing with a simple standalone Java
>> > application, doing so
>> > within a main method will suffice:
>> >
>> > package com.myco.app;
>> >
>> > import
>> >
>>
>> org.springframework.context.__annotation.__AnnotationConfigApplicationCon__text;
>> >
>> > import com.myco.domain.Foo;
>> > import com.myco.app.service.__FooService;
>> > import com.myco.app.config.__MyApplicationConfig;
>> >
>> > public class Bootstrap {
>> > public static void main(String... args) {
>> > AnnotationConfigApplicationCon__text ctx = new
>> > AnnotationConfigApplicationCon__text();
>> > ctx.register(__MyApplicationConfig.class);
>> > ctx.refresh();
>> >
>> > FooService fooService =
>> ctx.getBean(FooService.class);
>> > Foo foo1234 = fooService.findById(1234);
>> > System.out.println(foo1234);
>> > }
>> > }
>> >
>> >
>> > Now let's get to the business of method literals.
>> Notice
>> > again the
>> > Hibernate SessionFactory @Bean definition:
>> >
>> > @Bean
>> > public SessionFactory sessionFactory() {
>> > // ...
>> > }
>> >
>> >
>> > The SessionFactory is being created by Spring here,
>> and will
>> > be managed by
>> > the Spring container for the lifetime of the
>> ApplicationContext
>> > bootstrapped in our main method. Note however that its
>> > configuration is
>> > not yet complete - it is important to call a
>> > SessionFactory's close()
>> > method on application shutdown in order to manage
>> resources
>> > properly, and
>> > Spring provides a mechanism to allow users to specify
>> this
>> > with the
>> > 'destroyMethod' attribute of the @Bean annotation:
>> >
>> > @Bean(destroyMethod="close")
>> > public SessionFactory sessionFactory() {
>> > // ...
>> > }
>> >
>> > You can see the problem - 'close' must be specified as a
>> > string due to
>> > lack of method literal support in the language. Far
>> more
>> > desirable would
>> > be:
>> >
>> > @Bean(destroyMethod=__SessionFactory#close)
>> > public SessionFactory sessionFactory() {
>> > // ...
>> > }
>> >
>> > Whether the user is referring to an instance method or
>> > static method is,
>> > from the framework's point of view, immaterial. We
>> simply
>> > wish to provide
>> > the user with an IDE-friendly mechanism to execute a
>> method
>> > during the
>> > destruction phase of the bean lifecycle. We can do this
>> > already, but it
>> > requires stringification of method names.
>> >
>> > This is certainly not our only use case, but in the
>> interest
>> > of brevity
>> > I'll leave it here, noting that our use cases are not
>> > limited to method
>> > literals within annotations; such syntax would be useful
>> > within many
>> > contexts. For a non-Spring example, consider the case
>> of
>> > JPA 2's Criteria
>> > API, which is crippled by the lack of field literals
>> in the
>> > language. Its
>> > use is so cumbersome that the QueryDSL project has
>> become
>> > quite popular in
>> > conjunction with JPA, as they take an APT-based code gen
>> > approach that
>> > effectively approximates the functionality of field
>> literals
>> > [1]. Again, I
>> > find the utility of field and method literals
>> self-evident,
>> > even obvious.
>> > It is certainly not a Spring-specific itch we wish to
>> > scratch here, but
>> > rather to champion a generally useful addition to the
>> language.
>> >
>> > Are there fundamental objections to such support? Does
>> > prior art in
>> > Project Lambda already encompass these use cases?
>> We'd be
>> > interested in
>> > hearing what next steps are necessary to help make this
>> a
>> > reality in JDK 8
>> > and how we can help.
>> >
>> > Thanks,
>> >
>> > - Chris
>> >
>> > [1]:
>> > http://source.mysema.com/__forum/mvnforum/viewthread___thread,49
>> > <http://source.mysema.com/forum/mvnforum/viewthread_thread,49>
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > --
>> > @matthewadams12
>> > mailto:matthew at matthewadams.me <mailto:matthew at matthewadams.me>
>> <mailto:matthew at matthewadams.me <mailto:matthew at matthewadams.me>>
>> > skype:matthewadams12
>> > yahoo:matthewadams
>> > aol:matthewadams12
>> > google-talk:matthewadams12 at gmail.com
>> <mailto:google-talk%3Amatthewadams12 at gmail.com>
>> > <mailto:google-talk%3Amatthewadams12 at gmail.com
>> <mailto:google-talk%253Amatthewadams12 at gmail.com>>
>> > msn:matthew at matthewadams.me
>> <mailto:msn%3Amatthew at matthewadams.me>
>> <mailto:msn%3Amatthew at matthewadams.me
>> <mailto:msn%253Amatthew at matthewadams.me>>
>> > http://matthewadams.me
>> > http://www.linkedin.com/in/matthewadams
>> >
>>
>>
>
--
@matthewadams12
mailto:matthew at matthewadams.me
skype:matthewadams12
yahoo:matthewadams
aol:matthewadams12
google-talk:matthewadams12 at gmail.com
msn:matthew at matthewadams.me
http://matthewadams.me
http://www.linkedin.com/in/matthewadams
More information about the lambda-dev
mailing list