<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Thank you, I now understand whats going on, I just don’t like it that much.<div class=""><br class=""></div><div class="">C’est la vie,</div><div class=""><br class=""></div><div class="">Chris<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Dec 11, 2017, at 11:26 AM, Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" class="">maurizio.cimadamore@oracle.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" class="">
  
  <div text="#000000" bgcolor="#FFFFFF" class=""><p class="">Note that in your original example your second argument is:</p><p class="">o -> o.toString()</p><p class="">Whenever you have a lambda (implicit, or explicit) and the target
      type is some inference variable (like T in this case), the lambda
      is always considered potentially applicable (as per 15.12.2.1).</p><p class="">Then, since this is an implicit lambda - implicit lambda don't do
      much in terms of ruling out applicable candidates. This is called
      pertinence to applicability - see 15.12.2.2. An implicit lambda is
      NOT pertinent to applicability, so it doesn't contribute to
      overload resolution.</p><p class="">Hence, both methods in your example are applicable.</p><p class="">Maurizio</p>
    <br class="">
    <div class="moz-cite-prefix">On 11/12/17 14:59, Chris Dennis wrote:<br class="">
    </div>
    <blockquote type="cite" cite="mid:C46752CD-A797-46B0-B76B-ABFF12B7D1BC@gmail.com" class="">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" class="">
      Forgive me, it’s too long since I was at university, and then I
      was a physicist, so I just pretended to be good at
      mathematics/computer science. My intuitive understanding says that
      f(Consumer<T>, T>) shouldn't be considered applicable
      given the argument types (as per 15.12.2.3 <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.3" class="" moz-do-not-send="true">https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.3</a>).
       I’ve tried (and will continue to try) to work through the logic
      of that section and the accompanying details in Chapter 18, but if
      you could confirm that it is applicable then that would be great
      (at least then I’d know that what I’m doing is an academic
      exercise, and that I should end up proving the method is
      applicable).
      <div class=""><br class="">
      </div>
      <div class="">Thanks,</div>
      <div class=""><br class="">
      </div>
      <div class="">Chris<br class="">
        <div class=""><br class="">
          <div class="">
            <div class=""><br class="">
              <blockquote type="cite" class="">
                <div class="">On Dec 8, 2017, at 4:39 PM, Maurizio
                  Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" class="" moz-do-not-send="true">maurizio.cimadamore@oracle.com</a>>
                  wrote:</div>
                <br class="Apple-interchange-newline">
                <div class="">
                  <div class="">This is a tricky one - I'll try to
                    explain what's happening :-)<br class="">
                    <br class="">
                    FIrst, let's leave lambdas on the side - this has
                    nothing to do with it. And also simplify the program
                    as follows (I've also alpha-renamed the type vars):<br class="">
                    <br class="">
                    static <T> void f(Consumer<T> c, T o) {
                    }<br class="">
                    <br class="">
                    static <Z> void f(Consumer<Z> c, String
                    s) { }<br class="">
                    <br class="">
                    <br class="">
                    And consider the following invocation:<br class="">
                    <br class="">
                    f(null, null)<br class="">
                    <br class="">
                    Now, looking at the available signatures, one might
                    be tempted to conclude that the second signature is
                    most specific. But that's not how the rules in JLS
                    15.12.2.5 work  - those rule say that we need to do
                    two applicability tests:<br class="">
                    <br class="">
                    1) is f(Consumer<T>, T) applicable given
                    argument types { Consumer<Z>, String } ?<br class="">
                    2) is f(Consumer<Z>, String) applicable given
                    argument types { Consumer<T>, T } ?<br class="">
                    <br class="">
                    If the answer is yes to either (1) or (2), that
                    that's the most specific method; if (1) and (2) are
                    both true/false then the callsite is ambiguous.<br class="">
                    <br class="">
                    So, let's process the two questions:<br class="">
                    <br class="">
                    For (1) we have the following applicability tests
                    (note that _only_ Z acts as an an inference variable
                    in this test)<br class="">
                    <br class="">
                    Consumer<T> <: Consumer<Z><br class="">
                    T <: String<br class="">
                    <br class="">
                    now, no matter what we infer for Z, T<: String is
                    always going to be false. So (1) is not satisfied.
                    Let's move on to (2).<br class="">
                    <br class="">
                    For (2) we have the following applicability tests
                    (this time _only_ T acts as an inference variable)<br class="">
                    <br class="">
                    Consumer<Z> <: Consumer<T><br class="">
                    String <: T<br class="">
                    <br class="">
                    This looks more interesting. From the first
                    constraint we derive:<br class="">
                    <br class="">
                    Z = T<br class="">
                    <br class="">
                    But this means that, if we incorporate bounds,<br class="">
                    <br class="">
                    String <: T, T = Z --> String <: Z<br class="">
                    <br class="">
                    Which is, again, false.<br class="">
                    <br class="">
                    So, unfortunately, both applicability tests (1) and
                    (2) fails, so neither method is more specific. Hence
                    the ambiguity error.<br class="">
                    <br class="">
                    Cheers<br class="">
                    Maurizio<br class="">
                    <br class="">
                    <br class="">
                    <br class="">
                    <br class="">
                    On 08/12/17 17:34, Chris Dennis wrote:<br class="">
                    <blockquote type="cite" class="">Hi All,<br class="">
                      <br class="">
                      I’ve hit an interesting issue with an API that I
                      am responsible for whereby the equivalent to the
                      following does not compile:<br class="">
                      <br class="">
                      public class TargetTypingWeirdness {<br class="">
                      <br class="">
                        public static void test() {<br class="">
                          Consumer<String> stringConsumer =
                      System.out::println;<br class="">
                      <br class="">
                          f(stringConsumer, o -> o.toString());<br class="">
                        }<br class="">
                      <br class="">
                        static <T> Runnable f(Consumer<T> c,
                      T t) {<br class="">
                          return () -> c.accept(t);<br class="">
                        }<br class="">
                      <br class="">
                        static <T> Consumer<Object>
                      f(Consumer<T> c, Function<Object, T>
                      ft) {<br class="">
                          return o -> c.accept(ft.apply(o));<br class="">
                        }<br class="">
                      }<br class="">
                      <br class="">
                      with:<br class="">
                      <br class="">
                      TargetTypingWeirdness.java:9: error: reference to
                      f is ambiguous<br class="">
                          f(stringConsumer, o -> o.toString());<br class="">
                          ^<br class="">
                        both method
                      <T#1>f(Consumer<T#1>,T#1) in
                      TargetTypingWeirdness and method
                      <T#2>f(Consumer<T#2>,Function<Object,T#2>)
                      in TargetTypingWeirdness match<br class="">
                        where T#1,T#2 are type-variables:<br class="">
                          T#1 extends Object declared in method
                      <T#1>f(Consumer<T#1>,T#1)<br class="">
                          T#2 extends Object declared in method
                      <T#2>f(Consumer<T#2>,Function<Object,T#2>)<br class="">
                      TargetTypingWeirdness.java:9: error: incompatible
                      types: cannot infer type-variable(s) T<br class="">
                          f(stringConsumer, o -> o.toString());<br class="">
                           ^<br class="">
                          (argument mismatch; String is not a functional
                      interface)<br class="">
                        where T is a type-variable:<br class="">
                          T extends Object declared in method
                      <T>f(Consumer<T>,T)<br class="">
                      2 errors<br class="">
                      <br class="">
                      I’m trying to figure out if this is an allowed
                      behavior under the spec, or a bug in javac?<br class="">
                      <br class="">
                      Any help greatly appreciated,<br class="">
                      <br class="">
                      Chris<br class="">
                    </blockquote>
                    <br class="">
                  </div>
                </div>
              </blockquote>
            </div>
            <br class="">
          </div>
        </div>
      </div>
    </blockquote>
    <br class="">
  </div>

</div></blockquote></div><br class=""></div></body></html>