Primitives in Generics (+ the meaning of this)

Collin Fagan collin.fagan at gmail.com
Fri Jul 16 20:02:02 PDT 2010


There were many discussions previously about what 'this' should refer to.
Many times the lambdas/closures/whatever were based on interfaces or
function types. If I'm understanding things correctly it is now a goal to
allow abstract classes which have a SAM to be expressed as a lambda. If this
is the case then I would think changing what 'this' refers to is a bad idea.
A SAM interface expressed as lambda shouldn't (can't?) contain state on it's
own. In these use cases making 'this' refer to the lambda doesn't make a lot
of sense. If you want access to *any *state you need to go to the enclosing
scope to get it. This direction brought people to MethodHandel as a way of
implementing a lambda and the idea that lambdas are *not* objects. While
it's possible to have a SAM abstract class that does not have state, I would
not put money on it being the most common case. SAM abstract classes really
*are *objects. I'm not sure there is a way around that one. If it is an
object then we have to worry about identity, equality, new (implicit new?)
and all the other things that go along with being an object. Unfortunately
that also probably includes the meaning of 'this'.

This brings me back to what I consider the fundamental divide among the
participants on this list. Hopefully I've understood enough of the messages
here to separate the argument into two groups.

Group 1 prefers:

function types
lexical scoping
exception transparency
lexical break, return, continue
MethodHandle
and most importantly lambdas are *not* objects

Group 2 prefers:

interface SAM conversion
abstract class SAM conversion
local return, break, continue
'this' refers to lambda
identity is preserved
Method,Constructor and Field references.
more like anonymous inner classes
lambdas *are* objects

There is a word in java for types that aren't objects, primitives. I believe
group 1 wants *lambda primitives* and group 2 wants* *(or is willing to
tolerate)* lambda objects*. I'm not going to list who belongs to what group
but you know who you are. From the proposals so far I get the feeling that
the current Oracle work is focused more in the *lambda object* direction.
There could be some middle ground but obviously we haven't found it yet. Can
we have both? Is there a syntax for *lambda objects* that will leave the
door open later for* lambda primitives*?

Collin



On Fri, Jul 16, 2010 at 1:59 PM, Reinier Zwitserloot <
reinier at zwitserloot.com> wrote:

> Yes, the somewhat academic Aha! case.
>
> I think we can declare that as sufficiently rare that any arbitrary choice
> will work. Most likely that arbitrary choice can be: The meaning of
> "A.this"
> is itself resolved lexically, with the first matching scope winning the
> battle. Thus, In that example, A.this refers to the inner this. After all,
> the outer this can already be accessed via just 'this', so that works out
> nicely, and is (arguably!) the least surprising result.
>
>  --Reinier Zwitserloot
>
>
>
> On Fri, Jul 16, 2010 at 8:57 PM, Rémi Forax <forax at univ-mlv.fr> wrote:
>
> > Le 16/07/2010 20:45, Reinier Zwitserloot a écrit :
> > > The rather obvious answer would seem to be that implicit this refers to
> > the
> > > inner object, but explicit this defaults to the outer object. You can
> > still
> > > get an explicit this referencing the inner object by using the SAM type
> > as a
> > > qualifier.
> > >
> > > Thus:
> > >
> > > public class Example {
> > >      public void cancel() { System.out.println("OUTER"); }
> > >
> > >      public void runMe() {
> > >          TimerTask t = { ->
> > >              cancel(); //LINE 1
> > >              this.cancel(); //LINE 2
> > >              Example.this.cancel(); //LINE 3
> > >              TimerTask.this.cancel(); //LINE 4
> > >          };
> > >      }
> > > }
> > >
> > > In the above example, LINE 1 and LINE 4 cancel the timertask, whereas
> > LINE 2
> > > and LINE 3 just print "OUTER" to sysout.
> > >
> > > As has been said, everything is going to either be hard to understand
> or
> > not
> > > the thing one would expect in certain situations, and this is of course
> > no
> > > different - now there's a difference between unqualified invocation and
> > > this-qualified invocation for method calls, which doesn't normally
> happen
> > in
> > > java land. In my purely personal opinion on what's going to do the
> right
> > > thing and be the least surprising the most often, this one nevertheless
> > > wins.
> > >
> > > NB: As per the usual lexical scoping rules, if this was say a Runnable
> > and
> > > not a TimerTask, then LINE 1 would also print 'OUTER'.
> > >
> > >   --Reinier Zwitserloot
> > >
> >
> > And what about:
> > class A {
> >   public static void main(String[] args) {
> >     A a = { ->
> >        A.this;
> >     };
> >   }
> > }
> >
> > Rémi
> >
> > >
> > >
> > > On Fri, Jul 16, 2010 at 7:07 PM, Brian Goetz<brian.goetz at oracle.com>
> >  wrote:
> > >
> > >
> > >>> Regardless of that, do you aggree that the statistical evidence,
> > prepared
> > >>>
> > >> by some members of this list, showed that usage of explicit and
> implicit
> > >> "this" inside anonymous inner SAM subclass creation expressions is
> > >> practically non-existent and is actualy "in the way" of using
> outer.this
> > >> and/or outer instance members (even a cause of bugs in JDK itself)?
> > >>
> > >> No, I don't agree with this.  What we have is, basically, arguments
> over
> > >> which
> > >> use cases are more important and which error modes are worse, which
> are
> > >> almost
> > >> always just opinion contests, just like syntax discussions about which
> > >> alternative "looks more like Java".  Issues such as the one Josh
> raised
> > >> (where
> > >> TimerTask wants to call cancel()) come up with some frequency; so do
> > >> accidental shadowing of methods like toString() in inner classes.
>  This
> > >> generally just comes down to a "which error would you rather have"
> > >> question.
> > >> And, given that inner classes *already* suffer from the accidental
> > >> shadowing
> > >> problem, creating a mechanism that goes the other way (even if the
> other
> > >> way
> > >> is absolutely right!) is even more confusing for Java developers, who
> > now
> > >> have
> > >> to keep track of two separate and inconsistent bits of puzzlerhood.
> > >>
> > >> That said, the questions you raise here (and in your next e-mail) are
> > fair
> > >> and
> > >> we've already planned to devote some thought to it -- but not now,
> > because
> > >> we've got other things that demand our attention more urgently, such
> as
> > >> refining and implementing the features that are already in the
> must-have
> > >> column.
> > >>
> > >>
> > >>
> > >>
> > >
> >
> >
> >
>
>


More information about the lambda-dev mailing list