← Back to context

Comment by pjmlp

2 days ago

DLR inspired the addition of invokedynamic opcode on the JVM, which is actually the foundation for how lambdas get generated, many still think nested anonymous classes are used.

GraalVM already handles LLVM bitcode, much cooler than plain MSIL.

And here there is another example where Java ecosystem ends up being better.

MSR had a compiler framework similar to GraalVM, called Phoenix, it was going to replace VS, LLVM style, instead it died and what is left are a couple of research papers.

> many still think nested anonymous classes are used.

Anonymous classes are still used (sometimes). It simply depends on the circumstance of the lambda.

For example, this will result in a new anonymous class being generated.

    void foo(String s) {
      stream.filter(i->s.equals(i));
    }

The class gets generated to capture the `s` variable. Indy gets used in the `filter` method because the incoming lambda or method reference could be several types of method calls. For example, a constructor, an instance method, or a static method (I believe there are few more in the JVM bytecode).

What won't generate a new anonymous class is this sort of lambda

    stream.filter(i->"foo".equals(i));

That will generate a new method on the parent class which ultimately gets called. Since nothing is captured it can be directly called without a new instance being created.

  • I had another idea given Brian's talk on the matter.

    Never bothered to actually look into the generated bytecodes.

    • Surprisingly hard to find good docs on this. [1]

      I was wrong, it looks like the case I gave is one which doesn't result in a new anonymous class being generated. Instead the lambda metafactory gets involved to avoid that allocation.

      I apparently didn't see what I thought I saw. I thought that I had seen new `lambda.$1` classes being created in call stacks when debugging. Maybe I did, but the lambda was serializable (we have that in some unfortunate places in our code base).

      There are still cases where new classes get generated, but that's pretty much just for serialization.

      [1] https://cr.openjdk.org/~briangoetz/lambda/lambda-translation...