Lambda and JSR 292 method handle

tronicek at fit.cvut.cz tronicek at fit.cvut.cz
Wed Dec 30 00:12:40 PST 2009


Howard, could you elaborate this a bit? I can imagine the types which
extend the parameterized types. But I do not see how you want the compiler
to use them to check the relation between

>> List<? *extends* #String(Object)>

and

>> List<? *extends* #Object(String)>


Concerning the 'cast' method, it is useful at runtime. But how do you want
to check the relation between Callable$0<String> and Callable$String in
compiler?

Z.
-- 
Zdenek Tronicek
FIT CTU in Prague


Howard Lovatt napsal(a):
> Neal,
>
> Good points, the first:
>
>>
>
>> List<? *extends* #String(Object)>
>>
>
>
>> to a value of type
>>
>
>> List<? *extends* #Object(String)>
>>
>
>
>
> Is easily fixable by having the reified versions extend the generic
> versions
> with a special case for primitives, i.e.:
>
> *public* *abstract* *class* Callable$Int *implements* Callable$0<Integer>
> {
>   *public* *abstract* *int* callInt();
>   @Override *public* *final* Integer call() { *return* callInt(); }}
>
>
>
>> Also, there need to be subtype relations in both
>> directions between your Callable$0<String> and
>> Callable$String but that is impossible because they are
>> distinct interfaces. If you try to provide the subtype
>> relations in just one direction, things quicky get out of
>> hand (i.e. an exponential explosion in direct
>> superinterfaces of the generated interfaces) when there
>> are multiple lambda arguments.
>
> The above modification to implement Callable$... solves this problem in
> one
> direction and the other is via 'cast' methods. The idea was that the
> 'cast'
> methods are loader generated, though re-reading my post I didn't make this
> clear (sorry).
>
> I am making the assumption that these 'casts' are rare and therefore in
> practice you won't get an explosion of 'cast' methods.
>
>  -- Howard.
>
> 2009/12/29 Neal Gafter <neal at gafter.com>
>
>> There are a number of fatal problems with this approach.  The worst is
>> that
>> you can't use any explicit code to implement subtype conversions because
>> they don't work through generics.  For example, your scheme does not
>> provide
>> any way to convert a value of type
>>
>> *List<? extends #String(Object)>*
>>
>> to a value of type
>>
>> *List<? extends #Object(String)>*
>>
>> This conversion is just as important as the conversion on the underlying
>> function types.
>>
>> Also, there need to be subtype relations in both directions between your
>> *
>> Callable$0<String>* and *Callable$String* but that is impossible because
>> they are distinct interfaces.  If you try to provide the subtype
>> relations
>> in just one direction, things quicky get out of hand (i.e. an
>> exponential
>> explosion in direct superinterfaces of the generated interfaces) when
>> there
>> are multiple lambda arguments.
>>
>> Cheers,
>> Neal
>>
>>
>> On Tue, Dec 29, 2009 at 2:50 PM, Howard Lovatt
>> <howard.lovatt at iee.org>wrote:
>>
>>> You could reify lambda's, see:
>>>
>>> http://www.artima.com/weblogs/viewpost.jsp?thread=277879
>>>
>>> for details. This would solve many of the erasure 'issues'. But as
>>> Neal's
>>> example shows, not in all cases.
>>>
>>> 2009/12/23 Neal Gafter <neal at gafter.com>
>>>
>>>>  I don't think there is an option to reify function types.  That's
>>>> because generics are already non-reified.  In this code
>>>>
>>>> *<T> #T() constant(T t) {
>>>>     return #() t;
>>>> }
>>>> *
>>>>
>>>> the returned lambda cannot, in principle, be reified if generics are
>>>> not
>>>> reified.  This is independent of whether function types are mapped to
>>>> interfaces, method handles, or something else.  There may be issues
>>>> with it,
>>>> but they aren't "disadvantages" except by comparison to a scheme that
>>>> does
>>>> not have these issues, and no such scheme has been proposed.
>>>>
>>>>
>>>> On Wed, Dec 23, 2009 at 1:06 PM, Howard Lovatt
>>>> <howard.lovatt at iee.org>wrote:
>>>>
>>>>>  Presumably the problems with using generic style annotations and
>>>>> erasing the
>>>>> actual type include:
>>>>>
>>>>>   1. Can't have two methods of the same name only distinguished by
>>>>> lambda
>>>>>
>>>>>   type, e.g. filter( #boolean(int) ) and filter( #boolean(float) )
>>>>>
>>>>
>>>> These are distinguished in CfJ, but not in a hypothetical erasure to
>>>> MethodHandle.
>>>>
>>>>
>>>>>   2. Can't have arrays of lambdas that are type safe, e.g. new
>>>>> #(int)()[
>>>>> n
>>>>>   ]; // Illegal
>>>>>
>>>>
>>>> Right.
>>>>
>>>>
>>>>>   3. Can't have instanceof tests (this might be possible since type
>>>>>
>>>>>   information is carried at runtime)
>>>>>
>>>>
>>>> No, type information cannot, in principle, be guaranteed to be
>>>> available
>>>> at runtime unless generics are reified.
>>>>
>>>>
>>>>>   4. Can't have primitive types (this might be fixable with an
>>>>> extension
>>>>> to
>>>>>   the signature attribute)
>>>>>   5. Can't have static fields that are lambdas (this might be fixable
>>>>> with
>>>>>
>>>>>   an extension to the signature attribute)
>>>>>
>>>>
>>>> Right: the signature attributes would be extended to express function
>>>> types, addressing these two issues.
>>>>
>>>>
>>>> ______________________________________________________________________
>>>> This email has been scanned by the MessageLabs Email Security System.
>>>> For more information please visit http://www.messagelabs.com/email
>>>> ______________________________________________________________________
>>>>
>>>
>>>
>>>
>>> --
>>>  -- Howard.
>>>
>>
>>
>> ______________________________________________________________________
>> This email has been scanned by the MessageLabs Email Security System.
>> For more information please visit http://www.messagelabs.com/email
>> ______________________________________________________________________
>>
>
>
>
> --
>  -- Howard.
>
>



More information about the lambda-dev mailing list