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