Constructor references

Steven Simpson ss at comp.lancs.ac.uk
Fri Jan 14 05:04:21 PST 2011


Hi,

On 14/01/11 12:10, Peter Levart wrote:
> On 01/14/11, Maurizio Cimadamore wrote:
>> On 14/01/11 09:41, Rémi Forax wrote:
>>
>>> Something like:  new#Integer(int)
>>> which should be typed (int) ->  Integer.
>> That sounds entirely reasonable. I see few problems in the following cases:
>>
>> *) inner class creation, which might depend on an enclosing instance - 
>> do we want to treat the enclosing instance as an additional parameter?
>>
>> *) qualified new expressions - in this case it seems sensible to just 
>> add the explicit enclosing class reference to the MH (i.e. through bind).

It occurs to me that there might be some merit in keeping the LHS of #
exclusively for a normal expression, and the RHS for specifying a
method, including optional class.  That is, in the simple cases, an
instance method would be 'receiver#methodName' ('receiver' defaulting to
'this'), while a static method would be '#ClassName.methodName'.

This would leave open the possibility of 'receiver#ClassName.methodName'
if there was ever a case to distinguish between two instance methods
inherited from different classes.  (Could that issue arise with multiply
inherited defender methods?)

It also might help to resolve uncertainty about syntax choices for the
likes of these (with my suggestions inserted):

> public class Top
> {
>     class Inner
>     {
>         Inner(String s)
>         {
>         }
>     }
>
>     static class Nested
>     {
>         Nested(String s)
>         {
>         }
>     }
>
>     public Top()
>     {
>         // constructor invocations
>
>         Top.Inner inner1 = this.new Inner("yyy");
>         Top.Inner inner2 = new Inner("yyy"); // equivalent as above
>
>         Top.Nested nested1 = new Top.Nested("bbb");
>         Top.Nested nested2 = new Nested("bbb"); // equivalent as above
>
>         // constructor references
>
>         StringToInner f1 = this#new Inner;
>         StringToInner f2 = #new Inner; // equivalent as above
>         TopStringToInner f3 = Top#new Inner;

TopStringToInner f3 = #new Top.Inner;

Why splice the #new in-between to make Top#new Inner?  I think #new
Top.Inner is still distinguishable from #new Top.Nested, since the
compiler knows that one is static and the other not.

But what if you write this?:

StringToInner f2a = #new Top.Inner; // same as f2

It appears to be the same expression, but you can tell from the target
SAM type which one is meant, i.e. f2a could equivalently be assigned
this#new Top.Inner or #new Inner or this#new Inner, since both Top and
this are implied by context.

It also follows that you could write:

TopStringToInner f3a = #new Inner; // same as f3

...in the context of Top.  The expression appears to be the same as for
f2, but the target SAM type distinguishes them.

>         StringToNested f4 = #new Top.Nested;
>         StringToNested f5 = #new Nested; // equivalent as above
>     }
>
>     static
>     {
>         Top top = new Top();
>
>         // constructor invocations
>
>         Top.Inner inner = top.new Inner("xxx");
>                        // new Inner("xxx"); - illegal
>
>         Top.Nested nested1 = new Top.Nested("aaa");
>         Top.Nested nested2 = new Nested("aaa"); // equivalent as above
>
>         // constructor references
>
>         StringToInner f1 = top#new Inner;
>                         // #new Inner; - illegal
>         TopStringToInner f2 = Top#new Inner;

#new Top.Inner

>         StringToNested f3 = #new Top.Nested;
>         StringToNested f4 = #new Nested; // equivalent as above
>     }
>
>     interface StringToInner
>     {
>         Inner apply(String s);
>     }
>
>     interface TopStringToInner
>     {
>         Inner apply(Top t, String s);
>     }
>
>     interface StringToNested
>     {
>         Nested apply(String s);
>     }
> }

Cheers,

Steven



More information about the lambda-dev mailing list