Re: About the native-lambda branch
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
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
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 KingDatum: 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
On 13.01.2018 04:07, Nathan Harvey wrote: Sure thing. Here's a Java example: void sample(Functionfn) { 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
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