Method calls vs lambda calls

Howard Lovatt howard.lovatt at iee.org
Thu Dec 17 00:02:56 PST 2009


Based on Neal's generic example, here is a particularly nasty case:

class Base<T> {
  T t;
  T t1;
  void t() { out.println( t ); }
}

class Derived extends Base<#int()> {
  {
    t = #int() (42); // Can't override t() because it has a different signature
    t1 = #int() (41);
  }
  void test() {
    out.println( t1 ); // Prints Function_intATXXX
    out.println( t1() ); // Would be nice if this printed 41
    out.println( t ); // Prints Function_intATXXX
    out.println( t() ); // Error t() returns void
  }
}

I think this example leaves only three options:

1. The FCM solution of always using call(); i.e. in the example above,
out.println( t.call() ) and out.println( t1.call() ). This solution is
nice and simple.

2. You can only use t() to mean t.call() when there is no ambiguity;
i.e. in the example above, out.println( t.call() ) but out.println(
t1() ). People may well be confused by this since it is unlike the
rest of Java in both the way t() with the meaning t.call() is
'overloaded' and with when t() is valid shorthand for t.call().

3. Don't have function-types. This is the simplest solution and the
best fit with current Java since it retains nominal typing and
therefore by the KISS principle my favorite and importantly it does
not preclude adding function types later. This is similar to 1 above
if you define some interfaces, i.e. interface Callable0<R> { R call();
}, interface Callable1<R, A> { R call( A a); }, etc. Note 1 will still
require the interfaces for the JVM, but the programmer wouldn't use
them directly.

Can anyone think of any other options?

 -- Howard.

2009/12/16 Neal Gafter <neal at gafter.com>:
> On Wed, Dec 16, 2009 at 11:10 AM, Stefan Schulz <schulz at the-loom.de> wrote:
>>
>> Neal Gafter wrote:
>>>
>>> On Wed, Dec 16, 2009 at 6:36 AM, Stefan Schulz <schulz at the-loom.de
>>> <mailto:schulz at the-loom.de>> wrote:
>>>    I didn't say anything about making a method. If the short-hand
>>>    invocation syntax is allowed, putting names of function-typed
>>> variables
>>>    in the same (scope-relative) space like methods is a way to ensure not
>>>    to have methods and function-typed variables with the same name.
>>>
>>> I'm afraid it doesn't ensure that at all.  Because methods may overload,
>>> a given scope may have many definitions for a given name in the method
>>> namespace.
>>
>> Too bad. Is there any possibility to hold the full signature of methods
>> and function-typed variables in some way to being able to resolve these
>> conflicts? Maybe an additional function space? Sorry, if this sounds a bit
>> naive.
>
> I'm not sure what you're asking.  The mechanism for resolving these
> conflicts today is (compile-time) overload resolution.  It would have to be
> extended to handle the case of a mixture of methods and variables of
> function type.
>
>>>
>>>    As this
>>>    has to hold for inheritance, too, I do not see a problem in
>>>    function-typed variables of subclasses to @Override those of a
>>>    superclass, as the information is already there. (Of course, they must
>>>    additionally hide normal variables having the same name.)
>>>
>>>
>>> What semantics are you imagining for this overriding?  What if the thing
>>> being overridden is a method?
>>
>> I didn't mean to being able to override methods with function-typed
>> variables, or vice versa (although this sounds interesting).
>>
>> So, what would be the conclusion?
>> * If any method m exists in a class's hierarchy, one cannot define a
>> function-typed field m?
>> * If a function-typed field m exists in a class's hierarchy, one cannot
>> define a method named m?
>> * If a function-typed field m exists in a class's hierarchy, will a field
>> named m (of any type?) in a subclass hide the function-typed field m?
>> * If a non-function-typed field m hides a superclass's function-typed
>> field m, would it be possible to define a method named m in that very
>> subclass?
>
> Good questions, and there are many more.  Function-typed variables can be
> declared as local variables and parameters too.  They can also have a type
> of a generic parameter in a superclass but be inherited into a subclass as a
> function type:
>
> class Base<T> { T t; int t(int x) { return x; } }
> class Derived: Base<#int(int)> {}
>
> if Derived.t in the function namespace?
>
> A complete specification must provide clear answers to all these questions.
>
> Cheers,
> Neal
>
> ______________________________________________________________________
> 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