Field and Method Literals

Brian Goetz brian.goetz at oracle.com
Mon Nov 21 16:03:25 PST 2011


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
>      >
>
>


More information about the lambda-dev mailing list