Am 12.01.2018 um 15:00 schrieb Daniel Sun:
Hi Jochen,

but I think you should then not use the closure inner class mechanism.
I remain the implementation for non-native lambda[1] to make lambda work in
legacy code, where closures are widely used. For example, `[1, 2,
3].collect(e -> e + 1)`

ok, then forget about my other mail from a minute ago ;)

We have to be a bit careful here imho. Defining an inner class, means additional class loading times, accessing private fields becomes also more tricky. If you want to be able to be "equal" to the javac code as much as possible, then you should not base this on closure so much. In fact I think our closures should be based on lambdas instead. If we already had solved all the lambda problems, then I would change Closure accordingly actually. Yes, for a first step basing them on Closure is nice, but that can easily backfire.

For example

class SomeClass {
  private  foo;
  def m(bar) {
    SomeFunctionalInterface x =
       (it -> println "I am a lambda: $foo and $bar")
    return x
  }
}

Following the Closure route of dynamic Groovy means here the following:
(1) I create a Closure for the lambda as inner class, one such class per lambda
(2) I will ignore the overhead of the Closure instance generation
(3) I use the asType mechanism to create a dynamic proxy for my Closure
(4) If somebody creates a sublcass of Someclass accessing the private field foo gets complicated
(5) actually using the lambda would go through doCall/call
(6) accessing bar is realized through

and for the static case
* 1-3 and 5 will still apply. For point (4) there will be a bridging method (synthetic public static) in SomeClass, which is directly called to access the field. the static compiler is adding this method on its own (very very very late)

What I wish for in a static compile lambda is the following:
* bar is a parameter to the method generated for the lambda
* there is no groovy dynamic call involved to get to the lambda code
* the proxy for SomeFunctionalInterface is generated by the lambda factory
* foo is accessed directly through get field

And what I would wish for for the future Closure is. There is no inner class Closure anymore, instead Closure is just a holder for symbolic references and maybe some instances. Bar for example would still come in through the constructor. The Closure instance itself would be a parameter to the lambda method implementation (together with owner and such). And finally: there is a way to define a stateless Closure (but maybe the lambdas are the way for this)

I thought you need that only to enable reflection to find your inner
classes.
Could you make it a bit detail? To be honest, I can not get your words...

If you use reflection on a class you can ask this class what inner classes it has. For this there is in bytecode an entry in the inner class table. The inner class has an outer class attribute which can be used by Reflection to query for the enclosing class (similar for enclosing method). For the JVM itself I think those all are not required. The JVM does not care if a class is Bar or Foo$Bar and if the constructor takes an instance of Foo or not unlesss you call that constructor. The JVM even requires those bridge methods to access the private fields of the enclosing class. Which is also the reason why Groovy had this information wrong for a long time and not very many did really care.

bye Jochen

Reply via email to