this should not refer to the lambda

Alex Blewitt alex.blewitt at gmail.com
Sun Feb 21 08:44:18 PST 2010


On 21 Feb 2010, at 15:26, Rémi Forax <forax at univ-mlv.fr> wrote:

> Just a last example: I don't want to explain why 'this' doesn't mean
> the same thing in the two codes:
>
> Object[] array = { this };    // here this doesn't refer to the array
>
> #Object() fun = #() (this);  // here this refer to the lambda ??

This argument is somewhat tautologous. "I'd have difficulty in  
explaining it because I don't like what it means".

>
Object o = new Runnable() { void run() { this;} }// this refers to the  
runnable, not the enclosing object.

The # is a lot more like the Runnable than the block case; you are  
(potentially) instantiating a new "thing" (it can throw OOM) and that  
thing has reference semantics, much like an instance would. A block  
cannot throw an OOM nor does it have reference semantics.

Note that I am not assuming any particular implementation of # but  
these effects follow from the fact that # may be a closure over local  
state (thus requiring a binding context to be created) and by virtue  
that a lambda may be passed around as a reference.

Even if there is a third type of top-level  element added to the  
language, the it-doesn't-fit-my-mental-model-of-what-I'd-like-it-to-be  
is not a good reason one way or another. What we have to ensure is  
that we explain it in a way that people can conceptualise, and to  
ensure that the # is treated as a psuedo-new operator to ensure that  
it doesn't become a source of memory leaks.

(I use pseudo-new here because it shouldn't always create a new  
instance, particularly when no local scope is captured.)

But having a potentially instance-creating, reference based type and  
then disallowing the use of the operator in Java which is used to  
refer to self-instances seems (to me) inconsistent with the language  
as is (though of course, this is about changing the language).

And, as noted elsewhere, the ablility to reference the enclosing type  
is not hindered in any way if "this" does refer to the lambda. As for  
the nested lambda case, this is also possible (either implicitly due  
to local state capture or explicitly) without having to resort to  
language gymnastics like letting an RHS expression refer to the LHS  
type.

public class A {
   public class B {
     public void foo() {
       #() {
         // Need to add this line if needed
         Object me = this;
         #() {
A.this; // A instance
B.this; // B instance
me; // outer lambda
this; // inner lambda
         }
       }
     }
   }
}

It seems this doesn't prevent anything and doesn't require self-refs  
to be designed as:

Object me = #() { me}

There is no other construct in Jaca where you can do:

Object foo = ... foo ...

Since on the RHS foo isn't in scope. And it'll cause merry hell for  
IDEs which are built to assume that the RHS can't refer to an LHS  
assignment - a not unreasonable assumption in any language. (This may  
also break refactoring concepts as well; whilst there will obviously  
extensions which will be needed to treat lambdas in the general case,  
the being able to refer to the LHS from the RHS is the primary issue.)

Still, I suppose we couldn't screw up more than generics, so if we do  
allow RHS to use LHS then it will just be another future pain point  
for Java programmers of the future.

Alex
  


More information about the lambda-dev mailing list