[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-lambda-spec-observers
Subject:    Re: 15.28.1 needs some polish ?
From:       Ali Ebrahimi <ali.ebrahimi1781 () gmail ! com>
Date:       2013-02-24 10:19:00
Message-ID: CAA0cW5BJV-=Y95dw=FFAv7ith5wnV0uP1khA+C1r5Yaq1Jk_PQ () mail ! gmail ! com
[Download RAW message or body]

Hi Dan,
with current spec, resolving method references in overloaded generic method
contexts fails and gives ambiguity error.
Consider two scenario:

    interface Sam1<X> {
        void m(X x);
    }
    interface Sam2<X,Y> {
        void m(X x,Y y);
    }
1) scenario that we have two target types with arity n and n+1 and one
method

class Test {

void m(String s) { }

static <U> U u(Sam1<U> s) {       return null; }
static <U,T> U u(Sam2<U,T> s) {       return null; }

static void testUnbound() {
         Test s = u(Test::m);
}


2) scenario that we have two methods with arity n and n+1 and one target
type with arity n+1

class Test {

void m() { }
void m(String s) { }

static <U> U u(Sam1<U> s) {       return null; }

static void testUnbound() {
         Test s = u(Test::m);
}

Best Regards,
Ali Ebrahimi

On Wed, Feb 20, 2013 at 4:43 AM, Dan Smith <daniel.smith@oracle.com> wrote:

> On Feb 17, 2013, at 5:06 AM, Srikanth S Adayapalam <
> srikanth_sankaran@in.ibm.com> wrote:
>
> > Hello !
> >
> > (1) 0.6.1, 15.28.1 reads:
> >
> > -----------------------
> > Given a function descriptor with parameter types P1..Pn, the
> compile-time declaration for a method reference is determined as follows.
> >
> > If the method reference is qualified by a ReferenceType, two searches
> for a most-specific applicable method are performed, following the process
> outlined in 15.12.2. Each search may produce a method or, in the case of an
> error as specified in 15.12.2, no result.
> > First, the reference is treated as if it were an invocation of a method
> named by Identifier with argument expressions of types P1..Pn; the type to
> search is the ReferenceType; the type arguments, if any, are given by the
> method reference.
> >
> > Second, if P1..Pn is not empty and P1 is a subtype of ReferenceType, the
> reference is treated as if it were an invocation of a method named by
> Identifier with argument expressions of types P2..Pn. If the ReferenceType
> is a raw type, and there exists a parameterization of this type, G, that is
> a supertype of P1, the type to search is G; otherwise, the type to search
> is the ReferenceType. Again, the type arguments, if any, are given by the
> method reference.
> >
> > If both of these searches match a method, the reference is considered
> ambiguous.
> >
> > Otherwise, if the first search matches an instance method or the second
> search matches a static method, no method is chosen.
> >
> > Otherwise, if one of the searches matches a method, that is the
> compile-time declaration.
> > ----------------------------
> >
> > The first mention of static occurs in the penultimate sentence of the
> quoted text: Does that mean the following program
> > should be declared ambiguous ? (8b74 compiles this fine, but at run time
> there is an NPE) - There is no real ambiguity here.
> >
> > // ----
> > interface I {
> >   void zoo(Y y, String s);
> > }
> >
> > class Y {
> >         void zoo(String s) {
> >                 System.out.println("Y.zoo(String)");
> >         }
> >         void zoo(Y y, String s) {
> >                 System.out.println("Y.zoo(Y, String)");
> >         }
> > }
> >
> >
> > public class X  {
> >     public static void main(String[] args) {
> >             I i = Y::zoo;
> >             i.zoo(null,  null);
> >         }
> > }
> > // -----------
> >
> > I think this calls for a reordering of clauses and perhaps some
> rewording ?
> > The sentence "Otherwise, if the first search matches an instance method
> or
> > the second search matches a static method, no method is chosen." is a bit
> > vague ? i.e does this mean "No method is chosen as the compile
> declaration
> > of the method reference" or that "these matches are eliminated from
> further
> > reckoning ?"
> >
> > Also the sentence "If both of these searches match a method, the
> reference
> > is considered ambiguous." preceding the first utterance of 'static' would
> > render the program above illegal.
> >
> > Or reword the passage "First, the reference is treated as if it were an
> > invocation of a method" to "First, the reference is treated as if it
> were an
> > invocation of a _static_ method" and likewise massage the second part
> too ?
>
> This is an intentional design choice, although I think it's not quite
> right.
>
> The goal is to mimic the behavior of 15.12: a "static" method invocation
> can match an instance method, and it's only after a most-specific
> applicable method is chosen that an error occurs (per 15.12.3).
>  Generalizing, the search for a method is not supposed to take
> 'static'-ness into account.  (If anybody feels like this hasn't been
> sufficiently discussed, though, I acknowledge that this is a bit of a leap
> and we can debate it more...)
>
> So your example should be an error.
>
> In addition, 'static'-ness shouldn't affect resolution of an enclosing
> method invocation (e.g., 'overloadedMethod(Foo::m)'), any more than type
> arguments do (e.g., 'overloadedMethod(Foo<Bar>::m)'), so the check should
> wait to happen until after compatibility has been established.  So I've
> removed the sentence in question entirely, and added a similar restriction
> to the bulleted list that starts with "A method or constructor reference
> may be illegal even if it is compatible with its expected type".
>
> —Dan
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic