Notes on implementing concise calls to constructors with type parameters

Howard Lovatt howard.lovatt at iee.org
Thu May 21 18:57:28 PDT 2009


Peter,

Comments in-line.

2009/5/22 Peter Levart <peter.levart at gmail.com>:

[snip]

> ... and you forgot "consistency". That means features should be orthogonal.
> If it works that way in one context it should work the same way in all
> contexts. Consistency increases simplicity. What you propose is something
> that would work differently for constructors than for example inference
> works in generic methods. This would not achieve your ultimate goal.

But I want to do something that is different, I want to infer both the
class and the generic parameters - not just the generics.

[snip]

> In order for the compiler to allow Peter Ahe's example and not allow the
> exploit above, it would have to even further "complicate" the algorithm and
> include special cases for local or final variables. This might be an idea
> for a project COIN proposal if it bothered many people. But no such proposal
> was seen on this list, so we could assume it doesn't bother to many people.

Your example was nicely written, but as I said in my post "I do know
why it fails".

[snip]

> Yes, but the following works:
>
>         IntA<String, Integer> a = ClsA.instance();
>         IntA<String, Integer> b = ClsB.instance();
>
> ... it's just a matter of further "complicating" the inference algorithm in
> combination with overloaded methods. I read on this list that today the
> theory can do it.

The main point I was making was that a simple to understand algorthim
optimised for common use cases is the optimum choice.

[snip]

>  It might work well for straightforward cases but will be unusable for many
> others. And It might bring a lot of surprises. For example:
>
> public class InferenceTest
> {
>     interface IntA<X, Y>
>     {
>     }
>
>     static class ClsA<X, Y> implements IntA<Y, X> // note the reversal of X
> & Y
>     {
>     }
>
>     static void inferenceTest()
>     {
>         IntA<String, String> a = new ClsA();    // inferred as new
> ClsA<String, String>();
>         IntA<Integer, Integer> b = new ClsA();  // inferred as new
> ClsA<Integer, Integer>();
>         IntA<String, Integer> c = new ClsA();   // produces raw type new
> ClsA(); ???
>     }
> }

The line IntA<String, Integer> c = new ClsA() would br translated into
IntA<String, Integer> c = new ClsA<String, Integer>(), which would
fail with an error message clearly indicating the type mismatch -
therefore I would say that textual substitution works extremely well
on your example (it is in fact ideal). Ulf has given similar examples
on the forum and shown how generating errors for these cases is highly
desirable since they are most commonly caused by typos.

> I think the "textual substitution and fall back to raw type if it doesn't
> compile" is not a serious algorithm for any compiler or language. It is
> simply not consistent. I think we can do better. Java should only get the
> best.

I agree with your sentiment that the best algorithm should be chosen -
perhaps you can suggest one that works well, is optimised for, for the
common cases, doesn't produce poor error messages, is simply
understood, can be explained easily, is compatible with existing code,
and can infer both type and generic parameters. As demonstrated, the
current algorithms in javac can't do that. I don't mean the above
challenge rhetorically or sarcastically, I am not wedded to "my"
algorithm - if a better one exists lets use it.

Cheers,

 -- Howard.

>
> Regards, Peter
>
>>
>> Cheers,
>>
>>  -- Howard.
>>
>> >
>> > Peter.
>> >
>> >
>> > On Mon, May 18, 2009 at 10:13 AM, Howard Lovatt <howard.lovatt at iee.org>
>> > wrote:
>> >>
>> >> Hi Neal,
>> >>
>> >> Yes I should have spelled this out, it is one of those things obvious
>> >> to the author but not to the reader. I would propose that given more
>> >> than one method of the same name, method in example below, with the
>> >> general declaration for each following the syntax:
>> >>
>> >> ... method ( typeLHS [<genericParametersLHS>] name , ... ) { ... }
>> >>
>> >> and given the call:
>> >>
>> >> ... method ( new [typeRHS] [<genericParametersRHS>] ( ... ) , ... );
>> >>
>> >> Then a three step procedure would be used:
>> >>
>> >> 1. If typeRHS is absent assume for step 2 type Void, where Void is the
>> >> bottom type (in Java 7 this may be called Null but I chose Void to be
>> >> consistent with the InvokeDynamic proposal)
>> >>
>> >> 2. Resolve method as normal and hence find typeLHS and if specified
>> >> genericParametersLHS also
>> >>
>> >> 3. Apply textual substitution algorithm, i.e. If typeRHS is absent
>> >> substitute typeLHS and if genericParametersRHS is absent and
>> >> genericParametersLHS is present then substitute genericParametersLHS
>> >>
>> >> For example, given two methods:
>> >>
>> >> void method( Object notUsed ) { out.println( "Object" );  }
>> >> void method( String notUsed ) { out.println( "String" );  }
>> >>
>> >> The call:
>> >>
>> >> method( new() );
>> >>
>> >> would print String because it would be translated by the textual
>> >> substitution algorithm into method( new String() ), i.e. the same
>> >> behaviour as method( null ) because null has type Void (bottom).
>> >>
>> >> Does that add sufficient clarity? I would be really interested if you
>> >> can see a problem with the technique?
>> >>
>> >> If not the method maybe a good solution as it has many desirable
>> >> characteristics (as listed in previous posts in this thread). I also
>> >> note that many people would like a var or auto style declaration and
>> >> maybe this proposal of text substitution can satisfy more people than
>> >> other proposals, since it retains LHS types but saves re-specification
>> >> of type, generic type, and doesn't require a diamond operator on the
>> >> RHS.
>> >>
>> >>  -- 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 coin-dev mailing list