Fwd: Valid java 5 code refuses to compile with lambda-8-b81-linux-x64-12_mar_2013

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Mar 18 07:06:07 PDT 2013


On 17/03/13 20:39, Grégoire Neuville wrote:
> Yes, I noticed that (lb.<C>apply(map(f)) also works).
>   But with a jdk 7 or former, you don't need to explicitly type the
> expression for it to compile.
> Looks like a bug or a regression to me : jdk1.8 was intended to provide a
> (far) better type inference. That's clearly not the case here...
This is a straight compiler bug - the compiler knows that map.M = 
Func<Bind.B, Bind.C> and M = Func<Bind.B, Apply.B> - so it should derive 
Apply.B = Bind.C; but this derivation step is missing in the compiler 
which ends up inferring Apply.B = Object. This should obviously be fixed.

Maurizio
>
>
> On 17 March 2013 20:14, Sam Pullara <sam at sampullara.com> wrote:
>
>> Looks like the confusion is in type inference. If you have an explicit
>> type it does work:
>>
>>          <B, C> List<C> bind(final List<B> lb, final Func<A, Func<B, C>> f)
>> {
>>              List<Func<B, C>> map = map(f);
>>              return lb.apply(map);
>>          }
>>
>> Sam
>>
>> On Sat, Mar 16, 2013 at 4:17 PM, Grégoire Neuville
>> <gregoire.neuville at gmail.com> wrote:
>>> Hello,
>>>
>>> First of all, let me thank and congratulate you for the hard work you're
>>> putting into adding a functional tone to java : this is a great move that
>>> will undoubtedly prove itself immensely beneficial.
>>>
>>> That being said, I'm having a hard time compiling some basic java 5 code
>>> with the binary pre-release of both the bare jdk 1.8 and the
>>> lambda-enriched one. Indeed, trying to compile the below code :
>>>
>>> <code>
>>>
>>>   public class TestJ8 {
>>>
>>>      interface Func<A, B> {
>>>          B f(A a);
>>>      }
>>>
>>>      class List<A> {
>>>
>>>          <B> List<B> map(Func<A, B> f) {
>>>              return null;
>>>          }
>>>
>>>          <B> List<B> bind(Func<A, List<B>> f) {
>>>              return null;
>>>          }
>>>
>>>          <B> List<B> apply(final List<Func<A, B>> lf) {
>>>              return lf.bind(this::map);
>>>          }
>>>
>>>          <B, C> List<C> bind(final List<B> lb, final Func<A, Func<B, C>>
>> f) {
>>>              return lb.apply(map(f)); // fails to compile
>>>          }
>>>
>>>      }
>>>
>>> }
>>>
>>> </code>
>>>
>>> fails with the given message :  error: method apply in class
>> TestJ8.List<A>
>>> cannot be applied to given types
>>>
>>> Is it expected behaviour or am I missing something (installation steps or
>>> whatever...) ?
>>>
>>> Note : The compiler is invoked through maven with the following
>>> configuration :
>>>
>>> <plugin>
>>>              <groupId>org.apache.maven.plugins</groupId>
>>>              <artifactId>maven-compiler-plugin</artifactId>
>>>              <version>3.0</version>
>>>              <configuration>
>>>                  <verbose>true</verbose>
>>>                  <fork>true</fork>
>>>                  <executable>/usr/lib/jvm/java8/bin/javac</executable>
>>>                  <compilerArgument>-g</compilerArgument>
>>>                  <compilerVersion>1.8</compilerVersion>
>>>                  <source>1.8</source>
>>>                  <target>1.8</target>
>>>              </configuration>
>>> </plugin>
>>>
>>> Thanks !
>>>
>>> --
>>> Grégoire Neuville
>>>
>
>



More information about the lambda-dev mailing list