peter

Neal Gafter neal at gafter.com
Tue Feb 9 16:09:13 PST 2010


Like your previous proposals, this isn't sound.  I can't tell which way it
fails: either your arrays can't store lambdas that were created inside
generic methods (you get an array store exception).  Or, if that does work,
then your arrays can be assigned lambdas of the wrong type inside a generic
method.

The reason I can't tell which way it fails is that the specification isn't
coherent.  I tried reading the specification, (section 5), but immediately
ran into problems.  For example, starting with section 5.1, you don't say
what you mean for a type to be "generic", and the JLS doesn't provide a
definition that appears to match your meaning (in the JLS, the word is an
adjective used to describe declarations, not types).  In describing the
expansion (still section 5.1), when both the return and argument types are
"generic" types you have the names of the types of the function arguments
and return type encoded into the generated class name.  (You specify the
generated class *name *but not what the compiler ought to generate for it)
But if these "generic" types are type parameters, those names are not
unique, nor are they types that can be used outside the declaration of which
they are type parameters.  The translation in 5.1 only works when there is
precisely one lambda parameter (not zero or two).  Similarly, section 5.2
falls apart in the presence of primitives.  I didn't bother reading
further.  A more coherent analysis would require a coherent specification.

On Tue, Feb 9, 2010 at 3:17 PM, Howard Lovatt <howard.lovatt at iee.org> wrote:

> This proposal:
>
> http://www.artima.com/weblogs/viewpost.jsp?thread=278567
>
> Would allow:
>
> #Object(String)[] array = new #String(Object)[10];
>
> It would be translated into:
>
> _Callable_Object_String[] array =
> _Array_From_String_Object__To_Object_String.instance( new
> _Callable_String_Object[10] );
>
> A more interesting example is:
>
> final #String(Object)[] sols = new #String(Object)[1];
> sols[0] = #String(final Object o)(o.toString());
> final #Object(String)[] osls = sols;
> System.out.println("osls[0].(\"Hello\") = " + osls[0].("Hello"));
>
> Which is translated to:
>
>    final _Callable_String_Object[] sols = new _Callable_String_Object[1];
>    sols[0] = new _Callable_String_Object() {
>      @Override public String call(final Object o) { return o.toString(); }
>    };
>    final _Callable_Object_String[] osls =
> _Array_From_String_Object__To_Object_String.instance( sols );
>    System.out.println("osls[0].(\"Hello\") = " + osls[0].call("Hello"));
>
> _Array_From...'s instance method does all the necessary translation -
> see reference above for details. To give an idea of the scheme, the
> relevant 'From' classes are:
>
>  public final class _Array_From_String_Object__To_Object_String {
>    public static _Callable_Object_String[] instance(final
> _Callable_String_Object[] from) {
>      if (from == null) { return null; }
>      final _Callable_Object_String[] to = new
> _Callable_Object_String[from.length];
>      for (int i = 0; i < from.length; i++) { to[i] =
> _From_String_Object__To_Object_String.instance(from[i]); }
>      return to;
>    }
>  }
>
>  public final class _From_String_Object__To_Object_String extends
> _Callable_Object_String implements Wrapper {
>    private final _Callable_String_Object f;
>    private _From_String_Object__To_Object_String(final
> _Callable_String_Object f) { this.f = f; }
>    public static _From_String_Object__To_Object_String instance(final
> _Callable_String_Object from) {
>      if (from == null) { return null; }
>      final _Callable_String_Object f =
> (_Callable_String_Object)Wrappers.unWrap(from);
>      return new _From_String_Object__To_Object_String(f);
>    }
>    @Override public Object call(final String a1) { return f.call(a1); }
>    @Override public Object getWrappee() { return f; }
>    @Override public int hashCode() { return f.hashCode(); }
>  }
>
> Also see reference for actual type names, _Callable_... are a
> simplification to allow easy testing of the idea, and the relevant
> classes, _Callable... and 'From' are dynamically generated by the
> class loader.
>
>  -- Howard.
>
>


More information about the lambda-dev mailing list