Re: About the native-lambda branch

2018-01-13 Thread Daniel.Sun
It seems that I found where go wrong.
The shared local variables in generated method body should have been
replaced with parameters. Let me try later :-)

Cheers,
Daniel.Sun




--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html


Re: About the native-lambda branch

2018-01-13 Thread Daniel Sun
Hi Jochen,

> What I wish for in a static compile lambda is the following: 
> * bar is a parameter to the method generated for the lambda

I am trying to make native lambda support sharing local variables, but ASM
reports the following error[1]:
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
at org.objectweb.asm.Frame.merge(Frame.java:1501)

Have you ever encountered similar problems? Looking forward to your
suggestions :-)

Cheers,
Daniel.Sun

[1]
https://github.com/apache/groovy/blob/b6ea72dbf2ee4ab63fb1b96569de609679807a34/src/test/groovy/transform/stc/LambdaTest.groovy#L258



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html


Re: Making @Immutable a meta-annotation

2018-01-13 Thread MG

Hi Paul,

now I get where you are coming from with @KnownImmutable. I agree with 
splitting the two concepts: Flexible & elegant :-)


Transferring the parameter name knownImmutables (which exists inside the 
@Immutable context) to the annotation name KnownImmutable (which has no 
such context) still does not work for me, though.
In addition having @Immutable = @KnownImmutable + @ImmutableBase 
violates the definition you give for @KnownImmutable, because either the 
class is "known to be immutable" = "immutable by implementation by the 
developer", or it becomes immutable through @ImmutableBase & Groovy...


What do you think about:
@IsImmutable
@ImmutableContract
@GuaranteedImmutable
instead
?

Thinking about this some more, still don't like @ImmutableBase. Sounds 
too much like a base class to me - and what would be the "base" 
functionality of being immutable ? Something either is immutable, or not 
(@ImmutableCore also fails in this regard ;-) ).

So still would prefer @ImmutableOnly o.s. ...

Cheers,
mg


 Ursprüngliche Nachricht 
Von: Paul King 
Datum: 13.01.18 13:17 (GMT+01:00)
An: MG 
Betreff: Re: Making @Immutable a meta-annotation

I should have explained the @KnownImmutable idea a bit more. I guess I 
was thinking about several possibilities for that in parallel. What I 
really think is the way to go though is to split out the two different 
aspects that I was trying to capture. One is triggering the AST 
transformation, the other is a runtime marker of immutability. With that 
in mind I'd suggest the following:


@KnownImmutable will be a marker interface and nothing more. Any class 
having that annotation will be deemed immutable.
E.g. if I write my own Address class and I know it's immutable I can 
mark it as such:


@KnownImmutable
class Address {
  Address(String value) { this.value = value }
  final String value
}

Now if I have:

@Immutable
class Person {
  String name
  Address address
}

Then the processing associated with @Immutable won't complain about a 
potentially mutable "Address" field.


Then we can just leave @ImmutableBase (or similar) as the AST transform 
to kick off the initial processing needed for immutable classes.
The @Immutable annotation collector would be replaced by the constructor 
annotations, ToString, EqualsAndHashcode and both ImmutableBase and 
KnownImmutable.
The name KnownImmutable matches existing functionality. Two alternatives 
to annotating Address with KnownImmutable that already exist would be 
using the following annotation attributes on @Immutable:
@Immutable(knownImmutableClasses=[Address]) or 
@Immutable(knownImmutables=[address]).


Cheers, Paul.



On Sat, Jan 13, 2018 at 1:43 PM, MG > wrote:


   Hi Paul,

   I think the core of the problem is, that @Immutable as a
   meta-annotation woud be better off being called something along the
   line of @ImmutableCanonical (see: If you do no need the
   immutability, use @Canonical), since it does not solely supply
   immutability support - then it would be natural to call the actual
   core immutability annotation just "Immutable".

   That is probably off the table, since it would be a breaking change
   - so we are stuck with the problem of naming the immutability
   annotation part something else.

   @ImmutableClass would imply to me that the "Class" part carries some
   meaning, which I feel it does not, since
   a) "Class" could be postfixed to any annotation name that applies to
   classes
   b) The meta-annotation should accordingly also be called
   "ImmutableClass"
   Because of that I find postfixing "Immutable" with "Class" just
   confusing. It also is not intuitive to me, which annotation does
   only supply the core, and which supplies the extended (canonical)
   functionality...

   I do not understand where you are going with @KnownImmutable (known
   to whom ?-) To me this seems less intuitive/more confusing than
   @ImmutableClass...).

   @ImmutableCore is similar to @ImmutableBase (because I intentionally
   based it on it :-) ), but different in the sense that it imho
   expresses the semantics of the annotation: Making the object purely
   immutable-only, without any constructors, toString functionality, etc.

   How about:
   @ImmutableOnly
   @PureImmutable
   @ModificationProtected

   @Locked
   @Frozen

   @Unchangeable
   @Changeless

   @InitOnly
   @InitializeOnly

   @Constant
   @Const

   @NonModifieable
   @NonChangeable

   ?
   mg



   On 12.01.2018 08:01, Paul King wrote:

@ImmutableCore is similar to @ImmutableBase - probably okay but I
don't think ideal. Another alternative would be @ImmutableInfo or
have an explicit marker interface with a different package, e.g.
groovy.transform.marker.Immutable but that might cause IDE
completion headaches. Perhaps @KnownImmutable as a straight marker
interface might be the way to go - then it 

Re: About the native-lambda branch

2018-01-13 Thread Jochen Theodorou

On 13.01.2018 04:07, Nathan Harvey wrote:

Sure thing. Here's a Java example:

void sample(Function fn) {
System.out.println("fn");
}

void sample(Supplier sp) {
System.out.println("sp");
}

These methods can exist side by side, and are called correctly even in cases
of Lambda, eg:

sample(s -> 123); // fn
sample(() -> 123); // sp

On the other hand, take this Groovy code:


​def sample(Function fn) {
 println "fn"
}

def sample(Supplier sp) {
 println "sp"
}


in theory we can resolve this, because we do know how many parameters 
the Closure has and in sample({ s -> 1 }) we know we have one, thus it 
should be the Function. What we cannot do with Closure is the following:


interface I1 {
  String m(String s)
}
interace I2 {
  Integer m(Integer i)
}
def c(I1 i1){}
def c(I2 i2){}
c(i -> i+1)
c(i -> i.toString())

What should not work even in Java is the following:

interface I1 {
  String m(String s)
}
interace I2 {
  String m(Integer i)
}
def c(I1 i1){}
def c(I2 i2){}
c(i -> (i+1).toString())
c(i -> i.toString())

that is because here the return type will give no additional 
information, so only the parameter type can work and i.toString() works 
for both, i+1 should in theory also work for both.


bye blackdrag


Re: About the native-lambda branch

2018-01-13 Thread Daniel Sun
Hi Jochen,

 Here is an example:

```
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test1 {
public static void main(String[] args) {
p();
}

public static void p() {
 Stream.of(1, 2, 3).map(e -> e + 1).collect(Collectors.toList());
}
}
```

Its bytecode is shown as follows, note `  public final static INNERCLASS
java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles
Lookup`, which I found is useless, so I removed it and all code works still
well.

```
// class version 52.0 (52)
// access flags 0x21
public class Test1 {

  // compiled from: Test1.java
  // access flags 0x19
  public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup
java/lang/invoke/MethodHandles Lookup

  // access flags 0x1
  public ()V
   L0
LINENUMBER 4 L0
ALOAD 0
INVOKESPECIAL java/lang/Object. ()V
RETURN
MAXSTACK = 1
MAXLOCALS = 1

  // access flags 0x9
  public static main([Ljava/lang/String;)V
   L0
LINENUMBER 6 L0
INVOKESTATIC Test1.p ()V
   L1
LINENUMBER 7 L1
RETURN
MAXSTACK = 0
MAXLOCALS = 1

  // access flags 0x9
  public static p()V
   L0
LINENUMBER 10 L0
ICONST_3
ANEWARRAY java/lang/Integer
DUP
ICONST_0
ICONST_1
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
AASTORE
DUP
ICONST_1
ICONST_2
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
AASTORE
DUP
ICONST_2
ICONST_3
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
AASTORE
INVOKESTATIC java/util/stream/Stream.of
([Ljava/lang/Object;)Ljava/util/stream/Stream;
INVOKEDYNAMIC apply()Ljava/util/function/Function; [
  // handle kind 0x6 : INVOKESTATIC
 
java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  // arguments:
  (Ljava/lang/Object;)Ljava/lang/Object;,
  // handle kind 0x6 : INVOKESTATIC
  Test1.lambda$p$0(Ljava/lang/Integer;)Ljava/lang/Integer;,
  (Ljava/lang/Integer;)Ljava/lang/Integer;
]
INVOKEINTERFACE java/util/stream/Stream.map
(Ljava/util/function/Function;)Ljava/util/stream/Stream;
INVOKESTATIC java/util/stream/Collectors.toList
()Ljava/util/stream/Collector;
INVOKEINTERFACE java/util/stream/Stream.collect
(Ljava/util/stream/Collector;)Ljava/lang/Object;
POP
   L1
LINENUMBER 11 L1
RETURN
MAXSTACK = 4
MAXLOCALS = 0

  // access flags 0x100A
  private static synthetic
lambda$p$0(Ljava/lang/Integer;)Ljava/lang/Integer;
   L0
LINENUMBER 10 L0
ALOAD 0
INVOKEVIRTUAL java/lang/Integer.intValue ()I
ICONST_1
IADD
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
ARETURN
MAXSTACK = 2
MAXLOCALS = 1
}

```

Cheers,
Daniel.Sun



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html