4

As I understand from reading this post about the new invokedynamic bytecode instruction in JDK 7, it makes it possible to call methods on the objects which are not statically defined in the object's class and have those method calls be resolved to some concrete static methods in some other class by intercepting the method call target resolution (the post gives an example).

Does this mean that Java 7 classes can have implicit methods like Scala has? If not how is implicit method resolution in Scala different from the invokedynamic method resolution?

Abhinav Sarkar
  • 22,313
  • 10
  • 78
  • 95

2 Answers2

13

It is completely unrelated. Implicits in scala are fully resolved at compile time. The compiler inserts something that you could as well have written yourself. If it cannot do that, at compile time, there is an error. InvokeDynamic is about finding the method at runtime and failing at runtime if it cannot be found.

Specifically, if you write in scala x.m() where there is no method m in type x, it will look for an implicit conversion, that is a function, say f, which is in scope (you could call f at this point), which is marked as implicit, which will accept x as a parameter, and whose result type has a method m (there are a lot more details in the rules, but this is the essence). If it finds such a method, then it will replace x.m() by the properly typed f(x).m(). It could just as well have been written that way in the code, and it would have to in java. If no such function f can be found, then there is a compile time error.

It happens just the same way if you call g(x) and x is not of the right type to be passed to g. If there is a function f such that f(x) has the proper type, then it will replace the code by g(f(x)). Again, you could have written that yourself in plain scala, and again, if there is no such method, it will not compile.

Dynamic is about not worrying too much at compile time whether there is an m method in x, and looking for one at runtime. This is how a dynamic language like JRuby or Groovy typically works. There is something related in scala, trait Dynamic (marked experimental).

kittylyst
  • 4,978
  • 20
  • 35
Didier Dupont
  • 28,478
  • 6
  • 67
  • 88
  • So `invokedynamic` cannot add dynamic methods to Java classes? – Abhinav Sarkar Aug 21 '11 at 12:52
  • Primarily, it is a change in the bytecode (more like a clever trick with its semantic if I read the post you linked correctly), which main goal is to ease the implementation of dynamic language on the JVM. Allowing dynamic call in java (definitely not a dynamic language) is a different question. Should they elect to do so, InvokeDynamic would make it more efficient. But such a thing has been implementable at the language level since reflection is available in the VM. – Didier Dupont Aug 21 '11 at 13:38
  • Had a quick look at the JSR, and it sound like it will indeed make dynamic call available in java (if I understand correctly, a reference may be cast to Dynamic without run time check, and calls made on a ref seen as Dynamic by the compiler are dynamic). Still, this has no relation at all with scala implicits. – Didier Dupont Aug 21 '11 at 13:50
  • 2
    @didierd According to [1], the `java.dyn.Dynamic` interface did not make it into Java the language. Instead, one should make reflective calls with `java.lang.invoke.MethodHandle` to get invokedynamic bytecode from Java. Scala's `Dynamic` trait is basically what `java.dyn.Dynamic` was supposed to be. Reference: [1] http://stackoverflow.com/questions/7031634/invokedynamic-from-source-code-in-jdk7 – Kipton Barros Aug 21 '11 at 15:41
  • @Kipton Thanks for this info. – Didier Dupont Aug 22 '11 at 11:14
5

The invokedynamic bytecode will help speed up dynamic languages on the JVM. It will also speed up accesses to structural types in Scala. The alternative to invokedynamic (and only option prior to JDK 7) is reflection, which is really slow.

Java-the-language is statically typed, and doesn't have features that use invokedynamic (apart from explicit reflective method calls using java.lang.invoke.MethodHandle, according to this question).

Scala implicits are actually statically resolved, and thus unrelated to invokedynamic. For details about how it works, see Daniel Sobral's excellent expose: Where does Scala look for implicits?

Community
  • 1
  • 1
Kipton Barros
  • 20,144
  • 3
  • 63
  • 77