Lambda and JSR 292 method handle

Zdenek Tronicek tronicek at fit.cvut.cz
Mon Jan 4 01:31:30 PST 2010


I see you added the hashCode and equals methods. But where did you solve
the problem of the get method?
How is translated the following:

> List<? extends #String(Object)> p1 = new ArrayList<#String(Object)>();
> #String(Object) q = p1.get(0);

Z.
-- 
Zdenek Tronicek
FIT CTU in Prague


> Howard,
>
> I would like to write something positive but unfortunately it does not
> work very well for me:
>
> List<? extends #String(Object)> p1 = new ArrayList<#String(Object)>();
>
> is translated to
>
> List<? extends Callable$1<? extends Object, ? super String>> p1 =
>     new ArrayList<Callable$1<Object, String>>();
>
> Then, I want to get an item from the list:
>
> #String(Object) q = p1.get(0);
>
> I would expect it is translated to
>
> Callable$String$Object q = p1.get(0);
>
> or
>
> Callable$1<Object, String> q = p1.get(0);
>
> But none of these is syntactically correct.
>
>
> So, probably it would be translated to
>
> Callable$1<? extends Object, ? super String> q = p1.get(0);
>
> which is not consistent with translation of #String(Object).
>
> Concerning the casting, it changes the object identity. So, for example,
> the comparison of references will not work:
>
> #String(Object) so = ...;
> #Object(String) os = so;  // casting
> if (so != so) {
>     System.out.println("oops!");
> }
>
> Z.
> --
> Zdenek Tronicek
> FIT CTU in Prague
>
>

Howard Lovatt napsal(a):
> Zdenek,
>
> I have updated the post to cover your example; thanks it is another
> difficult case that needs to be addressed. The updated  blog is at
> http://www.artima.com/forums/flat.jsp?forum=106&thread=277879&start=0&msRange=15.
> I have included a list example like the one you gave. For comparing
> lambda's
> you need to use equals not ==.
>
> Keep the difficult cases coming there may be more subtile bugs in the
> proposal that these examples will tease out.
>
> Cheers,
>
>  -- Howard.
>
> 2009/12/30 <tronicek at fit.cvut.cz>
>
>> 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.
>> >
>> >
>>
>>
>> ______________________________________________________________________
>> 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