Function types versus arrays

Alex Buckley Alex.Buckley at Sun.COM
Mon Feb 15 14:31:02 PST 2010


John Rose wrote:
> If a lambda is created by generic code, that code will be operating
> in terms of the bounds types of any type variables, so if the lambda
> is returned to code which "sees" only a certain instance of the
> generic type, the lambda will have a dynamic type which looks
> "unfinished" relative to the expectations of the calling code.  It
> may be that generic code can only be expected to build tightly-typed
> lambdas if it takes Class<T> arguments to go with relevant <T>
> parameters, so that lambdas can be created with the desired dynamic
> type.  For example, here are a couple of test cases:
> 
>   static <T, A extends T>
>   #(A)->T identityFunction()
>   // hard to infer A/T, must return concrete #(Object x)(x)
>   { return #(A x)(x); }
> 
>   static <T>
>   #()->T constantFunction(T x)
>   // must return concrete #()((Object)x)
>   { return type.cast( #()(x) ); }
> 
>   static <T, A extends T>
>   #(A)->T identityFunction(FunctionType<#(A)->T> type)
>   // assuming a suitable FunctionType.cast, all is well
>   { return type.cast( #(A x)(x) ); }
> 
>   static <T>
>   #()->T constantFunction(FunctionType<#()->T> type, T x)
>   { return type.cast( #()(x) ); }

Requiring FunctionType arguments is a red herring in my view. The caller 
of a generic method is also in a position to perform the cast. Indeed, 
the caller of the first (and second) example must do *something* since 
otherwise, invoking foo.<String,String>identityFunction() will return a 
function expected to return a String but which only returns Object.

(If the caller's cast is really a wrap, Neal objections w.r.t. object 
identity stand. But wrapping doesn't seem like the only option.)

Alex


More information about the lambda-dev mailing list