Re: Does not pertinent to applicability mean not used?

Timo Kinnunen timo.kinnunen at gmail.com
Wed May 7 10:11:51 UTC 2014


Taking this as an example:


static Optional<?> test(Stream<Stream<String>> stream2) {

  return stream2.map(stream -> stream.map(string -> Integer.parseInt(string))).findAny();

}


If not pertinent to applicability works as specified, then the inner “string -> Integer.parseInt(string)” actually means “string -> (Object) Integer.parseInt(string)” as compiled with current Javac. 


On the other hand, if a programmer were to write the inner lambda as “(String string) -> Integer.parseInt(string)”, repeating the type String “coming from the outside” redundantly, then the type Integer would be incorporated as normal.


This subtle difference between 


string -> Integer.parseInt(string)

versus


(String string) -> Integer.parseInt(string)

having the effects


string -> (Object) Integer.parseInt(string)

and


(String string) -> (Integer) Integer.parseInt(string)

is not useful. 


The specification should be changed so that Integer is incorporated in both cases.


If I got anything wrong please correct me.








-- 
Have a nice day,
Timo.

Sent from Windows Mail





From: Rafkind, Jon
Sent: ‎Thursday‎, ‎May‎ ‎1‎, ‎2014 ‎01‎:‎13
To: Zhong Yu, Timo Kinnunen
Cc: lambda-dev at openjdk.java.net





On 04/29/2014 06:45 PM, Zhong Yu wrote:
> If an argument is not pertinent to applicability, it is ignored during
> the applicability test. Other than that, I don't see what effect it
> has.
>
> Consider this simple code
>
>     void test(Stream<String> ss)
>     {
>         ss.map( s->Integer.parseInt(s) );
>     }
>
> The implicit lambda expression is not pertinent to applicability; it
> does not prevent the compiler from inferring that the invocation
> returns Stream<Integer>

I think this case is different because the lambda is added as an
additional constraint, as per 18.5.2:

"For all i (1 ≤ i ≤ k), additional constraints may be included,
according to the form of ei:
  If the expression is a LambdaExpression, the set contains
⟨LambdaExpression →throws Fi θ⟩."

FWIW, my compiler also reports an error on this line

Map<String, List<String>> methodReferenceVersionWithError() {
    return s2.flatMap(p -> entryToStream(p).map(p::replaceKey)).collect(c2);
}

When the type if flatMap() is inferred the constraint 'p ->
entryToStream ...' is added. Reducing that lambda constraint produces
the constraint 'map(p::replaceKey) -> Stream<%a1>', where map() is a
poly invocation. Reducing a poly invocation reduces to the set B3 that
is described in section 18.5.2 as per 18.2.1:

"If the expression is a class instance creation expression or a method
invocation, the constraint reduces to the bound set B3 which would be
used to determine the expression's invocation type when targeting T, as
defined in 18.5.2 (in the case of a class instance creation, the
corresponding "method" used for inference is defined in 15.9.3)."

But B3 ignores non-pertinent expressions so p::replaceKey is not used in
a constraint formula. B3 basically comprises the pertinent expressions
and the return type.


More information about the lambda-dev mailing list