Function types versus arrays

Rémi Forax forax at univ-mlv.fr
Mon Feb 15 16:40:22 PST 2010


Le 15/02/2010 23:31, Alex Buckley a écrit :
> 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.
>    

I agree.
Like with generics/erased code, the conversion must be done
at call site.

> (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.)
>    

In my opinion, object identity is not important here,
conversions like boxing/unboxing can already occur
at call site of a generics instantiation.

You only need to have object identity when you deal
with widening/narrowing conversions.

<T> #T() func(T t) {
   return #() (t);
}

func("foo")
can be translated to
func("foo").asType(ldc #String());

> Alex
>
>    

Rémi


More information about the lambda-dev mailing list