invokedynamic and implicit methods - java

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?

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).

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?

Related

Subtyping polymorphism: Always late binding?

This wikipedia states:
Since the specific type of a polymorphic object is not known before
runtime (in general), the executed function is dynamically bound.
Take, for example, the following Java code:
public void foo(java.util.List<String> list) {
list.add("bar");
}
List is an interface, so list must refer to a subtype of it. Is it a
reference to a LinkedList, an ArrayList, or some other subtype of
List? The actual method referenced by add is not known until runtime.
Consider this example:
List<String> list;
list = new LinkedList<String>();
foo(list);
list = new ArrayList<String>();
foo(list);
Why is the actual method referenced here is not know until runtime? Couldn't the compiler just check for each call of foo of which type the object list is assigned to? Of course this would be only possible if the program is deterministic and no randomness is involved (e.g. user interaction).
Is this what (in general) in the quoted statement is about or is my understanding wrong?
In the special case when the program is deterministic, is static binding used or is - in Java - always dynamic binding used, regardless of what is possible? If so, why?
The statement speaks about the general case. Given only the code of the Wikipedia example it is not possible to tell the concrete type of the list parameter. In your example it is possible to tell the concrete types.
The Java runtime is allowed and does in fact devirtualize method calls if it can detect the concrete type of a variable.
If you are interested in the topic: Here is a link to paper which discusses devirtualization techniques.
The devirtualization is not preformed during the compilation of java source to java bytecode. Otherwise this would be quite fragile. Note that compiled java classes usually preserve binary compatibility (with some known exceptions). Thus if your foo is located in the separate class and you recompile just this class, then the class calling foo should work with new code without recompilation.
However the devirtualization is possible at runtime and actually performed by most of modern JVMs (including Oracle HotSpot JVM, or course). This method is likely to be fully inlined during the JIT-compilation: both foo calls, LinkedList.add and ArrayList.add methods will be merged into the body of caller method.
So in general Wikipedia quote is correct: The actual method referenced by add is not known until runtime. However this does not mean that the call remains polymorphic as JVM runtime is quite complex thing which includes interpreter, JIT-compilation and execution of JIT-compiled code.

Why does erasure complicate implementing function types?

I read from an interview with Neal Gafter:
"For example, adding function types to the programming language is much more difficult with Erasure as part of Generics."
EDIT:
Another place where I've met similar statement was in Brian Goetz's message in Lambda Dev mailing list, where he says that lambdas are easier to handle when they are just anonymous classes with syntactic sugar:
But my objection to function types was not that I don't like function types -- I love function types -- but that function types fought badly with an existing aspect of the Java type system, erasure. Erased function types are the worst of both worlds. So we removed this from the design.
Can anyone explain these statements? Why would I need runtime type information with lambdas?
The way I understand it, is that they decided that thanks to erasure it would be messy to go the way of 'function types', e.g. delegates in C# and they only could use lambda expressions, which is just a simplification of single abstract method class syntax.
Delegates in C#:
public delegate void DoSomethingDelegate(Object param1, Object param2);
...
//now assign some method to the function type variable (delegate)
DoSomethingDelegate f = DoSomething;
f(new Object(), new Object());
(another sample here
http://geekswithblogs.net/joycsharp/archive/2008/02/15/simple-c-delegate-sample.aspx)
One argument they put forward in Project Lambda docs:
Generic types are erased, which would expose additional places where
developers are exposed to erasure. For example, it would not be
possible to overload methods m(T->U) and m(X->Y), which would be
confusing.
section 2 in:
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html
(The final lambda expressions syntax will be a bit different from the above document:
http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html)
(x, y) => { System.out.printf("%d + %d = %d%n", x, y, x+y); }
All in all, my best understanding is that only a part of syntax stuff that could, actually will be used.
What Neal Gafter most likely meant was that not being able to use delegates will make standard APIs more difficult to adjust to functional style, rather than that javac/JVM update would be more difficult to be done.
If someone understands this better than me, I will be happy to read his account.
Goetz expands on the reasoning in State of the Lambda 4th ed.:
An alternative (or complementary) approach to function types,
suggested by some early proposals, would have been to introduce a new,
structural function type. A type like "function from a String and an
Object to an int" might be expressed as (String,Object)->int. This
idea was considered and rejected, at least for now, due to several
disadvantages:
It would add complexity to the type system and further mix structural and nominal types.
It would lead to a divergence of library styles—some libraries would continue to use callback interfaces, while others would use structural
function types.
The syntax could be unweildy, especially when checked exceptions were included.
It is unlikely that there would be a runtime representation for each distinct function type, meaning developers would be further exposed to
and limited by erasure. For example, it would not be possible (perhaps
surprisingly) to overload methods m(T->U) and m(X->Y).
So, we have instead chosen to take the path of "use what you
know"—since existing libraries use functional interfaces extensively,
we codify and leverage this pattern.
To illustrate, here are some of the functional interfaces in Java SE 7
that are well-suited for being used with the new language features;
the examples that follow illustrate the use of a few of them.
java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
...
Note that erasure is just one of the considerations. In general, the Java lambda approach goes in a different direction from Scala, not just on the typed question. It's very Java-centric.
Maybe because what you'd really want would be a type Function<R, P...>, which is parameterised with a return type and some sequence of parameter types. But because of erasure, you can't have a construct like P..., because it could only turn into Object[], which is too loose to be much use at runtime.
This is pure speculation. I am not a type theorist; i haven't even played one on TV.
I think what he means in that statement is that at runtime Java cannot tell the difference between these two function definitions:
void doIt(List<String> strings) {...}
void doIt(List<Integer> ints) {...}
Because at compile time, the information about what type of data the List contains is erased, so the runtime environment wouldn't be able to determine which function you wanted to call.
Trying to compile both of these methods in the same class will throw the following exception:
doIt(List<String>) clashes with doIt(List<Integer); both methods have the same erasure

why MyClass.class exists in java and MyField.field isn't?

Let's say I have:
class A {
Integer b;
void c() {}
}
Why does Java have this syntax: A.class, and doesn't have a syntax like this: b.field, c.method?
Is there any use that is so common for class literals?
The A.class syntax looks like a field access, but in fact it is a result of a special syntax rule in a context where normal field access is simply not allowed; i.e. where A is a class name.
Here is what the grammar in the JLS says:
Primary:
ParExpression
NonWildcardTypeArguments (
ExplicitGenericInvocationSuffix | this Arguments)
this [Arguments]
super SuperSuffix
Literal
new Creator
Identifier { . Identifier }[ IdentifierSuffix]
BasicType {[]} .class
void.class
Note that there is no equivalent syntax for field or method.
(Aside: The grammar allows b.field, but the JLS states that b.field means the contents of a field named "field" ... and it is a compilation error if no such field exists. Ditto for c.method, with the addition that a field c must exist. So neither of these constructs mean what you want them to mean ... )
Why does this limitation exist? Well, I guess because the Java language designers did not see the need to clutter up the language syntax / semantics to support convenient access to the Field and Method objects. (See * below for some of the problems of changing Java to allow what you want.)
Java reflection is not designed to be easy to use. In Java, it is best practice use static typing where possible. It is more efficient, and less fragile. Limit your use of reflection to the few cases where static typing simply won't work.
This may irk you if you are used to programming to a language where everything is dynamic. But you are better off not fighting it.
Is there any use that is so common for class literals?
I guess, the main reason they supported this for classes is that it avoids programs calling Class.forName("some horrible string") each time you need to do something reflectively. You could call it a compromise / small concession to usability for reflection.
I guess the other reason is that the <type>.class syntax didn't break anything, because class was already a keyword. (IIRC, the syntax was added in Java 1.1.)
* If the language designers tried to retrofit support for this kind of thing there would be all sorts of problems:
The changes would introduce ambiguities into the language, making compilation and other parser-dependent tasks harder.
The changes would undoubtedly break existing code, whether or not method and field were turned into keywords.
You cannot treat b.field as an implicit object attribute, because it doesn't apply to objects. Rather b.field would need to apply to field / attribute identifiers. But unless we make field a reserved word, we have the anomalous situation that you can create a field called field but you cannot refer to it in Java sourcecode.
For c.method, there is the problem that there can be multiple visible methods called c. A second issue that if there is a field called c and a method called c, then c.method could be a reference to an field called method on the object referred to by the c field.
I take it you want this info for logging and such. It is most unfortunate that such information is not available although the compiler has full access to such information.
One with a little creativity you can get the information using reflection. I can't provide any examples for asthere are little requirements to follow and I'm not in the mood to completely waste my time :)
I'm not sure if I fully understand your question. You are being unclear in what you mean by A.class syntax. You can use the reflections API to get the class from a given object by:
A a = new A()
Class c = a.getClass()
or
Class c = A.class;
Then do some things using c.
The reflections API is mostly used for debugging tools, since Java has support for polymorphism, you can always know the actual Class of an object at runtime, so the reflections API was developed to help debug problems (sub-class given, when super-class behavior is expected, etc.).
The reason there is no b.field or c.method, is because they have no meaning and no functional purpose in Java. You cannot create a reference to a method, and a field cannot change its type at runtime, these things are set at compile-time. Java is a very rigid language, without much in the way of runtime-flexibility (unless you use dynamic class loading, but even then you need some information on the loaded objects). If you have come from a flexible language like Ruby or Javascript, then you might find Java a little controlling for your tastes.
However, having the compiler help you figure our potential problems in your code is very helpful.
In java, Not everything is an object.
You can have
A a = new A()
Class cls = a.getClass()
or directly from the class
A.class
With this you get the object for the class.
With reflection you can get methods and fields but this gets complicated. Since not everything is an object. This is not a language like Scala or Ruby where everything is an object.
Reflection tutorial : http://download.oracle.com/javase/tutorial/reflect/index.html
BTW: You did not specify the public/private/protected , so by default your things are declared package private. This is package level protected access http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

Is it possible for Scala to have reified generics without changing the JVM?

I've recently started learning Scala and was disappointed (but not surprised) that their generics are also implemented via type erasure.
My question is, is it possible for Scala to have reified generics, or would the JVM need to be changed in some way? If the JVM does need to be changed, what exactly would need to be changed?
No - it is not possible for Scala to run as Java-equivalent bytecode if that bytecode does not support reified generics.
When you ask "what is it that needs to be changed?", the answer is: the bytecode specification. Currently the bytecode does not allow for the parametrized type of a variable to be defined. It has been decided that as a modification to the bytecode to support reified generics would break backwards compatibility, that generics would have to be implemented via type erasure.
In order to get around this, Scala has used the power of its implicit mechanism to define a Manifest which can be imported in any scope to discover type information at runtime. Manifests are experimental and largely undocumented but they are coming as part of the library in 2.8. Here is another good resource on Scala reified generics / Manifests
Just to complement oxbow_lakes, there's a question on Stack Overflow about how to get around type erasure in Scala.
"implicit Manifest" is a Scala compiler trick and it does not make generics in Scala reified. The Scala compiler, when it sees a function with "implicit m: Manifest[A]" parameter and it knows the generic type of A at the call site, it will wrap the class of A and its generic type parameters into a Manifest and make it available inside the function. However, if it could not figure out the true type of A, then it has no way of creating a Manifest. In other words, Manifest has to be passed along the function calling chain if the inner function needs it.
scala> def typeName[A](a: A)(implicit m: reflect.Manifest[A]) = m.toString
typeName: [A](a: A)(implicit m: scala.reflect.Manifest[A])java.lang.String
scala> typeName(List(1))
res6: java.lang.String = scala.collection.immutable.List[int]
scala> def foo[A](a: A) = typeName(a)
<console>:5: error: could not find implicit value for parameter m:scala.reflect.Manifest[A].
def foo[A](a: A) = typeName(a)
^
scala> def foo[A](a: A)(implicit m: reflect.Manifest[A]) = typeName(a)
foo: [A](a: A)(implicit m: scala.reflect.Manifest[A])java.lang.String
scala> foo(Set("hello"))
res8: java.lang.String = scala.collection.immutable.Set[java.lang.String]
To complement oxbow_lakes answer: It is no possible and it seems it will never happen (at least soon).
The (refutable) reasons JVM will not support reified generics seems to be:
Lower performance.
It breaks backward compatibility. It can be solved duplicating and fixing a lot of libraries.
It can be implemented using manifests: The "solution" and the biggest impediment.
References:
Odersky comment in 2010: "I prefer a simpler VM architecture with type erasure"
In scala-internals list (Feb 2013) Grzegorz Kossakowski said:
You can easily benchmark it and see that performance impact is very
noticeable. Especially memory consumption increases a lot.
I believe the way to go is to have optional reification the way we
start to do in Scala with Manifests/TypeTags.
If you can and combine it with runtime specialization you can aim for
high performance and generic code. However, that's probably goal for
Scala 2.12 or 2.13.
Once scalac is a compiler, it has the potential of being able to embellish the generated code with whatever data structures are needed to implement reified generics.
What I mean is that scalac would have the ability to see...
// definition
class Klass[T] {
value : T
}
//calls
floats = Klass[float]
doubles = Klass[double]
... and "expand" to something like this:
// definition
class Klass_float {
value : float
}
class Klass_double {
value : double
}
// calls
floats = Klass_float
doubles = Klass_double
Edit
The point is: the compiler has the ability to create all necessary data structures which demonstrate to be necessary to provide additional type information at runtime. Once this type information is available, the Scala runtime would take advantage of it and could perform all type-aware operations we can imagine. It does not matter whether the JVM provides bytecode for reified generics or not. The work is not done by the JVM, but by the Scala library.
If you have already written a symbolic debugger (I did!), you know that you can basically 'dump' all information the compiler has at compile-time into the generated binary, adopting whatever data organization demonstrates to be more convenient for further processing. This is exactly the same idea: 'dump' all type information the Scala compiler has.
In a nutshell, I don't see why it could not be possible, does not matter whether the JVM provides native operations for reified generics or not. The JVM bytecode has nothing to do with reified generics. This sort of thing is a matter of language specification, compiler features and runtime library support.
Another edit
IBM X10 demonstrates the ability I'm talking of: it compiles X10 code onto Java code, leveraging reified generics onto Java platforms. As I mentioned before: it can be done (and IBM X10 did!) but this kind of feature involves language specification, compiler support (or compiler plugins) and enough support in runtime libraries. More info at: http://x10.sourceforge.net/documentation/papers/X10Workshop2012/slides/Takeuchi.pdf

Are there inline functions in java?

Is there a concept of inline functions in java, or its replaced something else? If there is, how is it used? I've heard that public, static and final methods are the inline functions. Can we create our own inline function?
In Java, the optimizations are usually done at the JVM level. At runtime, the JVM perform some "complicated" analysis to determine which methods to inline. It can be aggressive in inlining, and the Hotspot JVM actually can inline non-final methods.
The java compilers almost never inline any method call (the JVM does all of that at runtime). They do inline compile time constants (e.g. final static primitive values). But not methods.
For more resources:
Article: The Java HotSpot Performance Engine: Method Inlining Example
Wiki: Inlining in OpenJDK, not fully populated but contains links to useful discussions.
No, there is no inline function in java. Yes, you can use a public static method anywhere in the code when placed in a public class. The java compiler may do inline expansion on a static or final method, but that is not guaranteed.
Typically such code optimizations are done by the compiler in combination with the JVM/JIT/HotSpot for code segments used very often. Also other optimization concepts like register declaration of parameters are not known in java.
Optimizations cannot be forced by declaration in java, but done by compiler and JIT. In many other languages these declarations are often only compiler hints (you can declare more register parameters than the processor has, the rest is ignored).
Declaring java methods static, final or private are also hints for the compiler. You should use it, but no garantees. Java performance is dynamic, not static. First call to a system is always slow because of class loading. Next calls are faster, but depending on memory and runtime the most common calls are optimized withinthe running system, so a server may become faster during runtime!
Java does not provide a way to manually suggest that a method should be inlined. As #notnoop says in the comments, the inlining is typically done by the JVM at execution time.
What you said above is correct. Sometimes final methods are created as inline, but there is no other way to explicitly create an inline function in java.
Well, there are methods could be called "inline" methods in java, but depending on the jvm. After compiling, if the method's machine code is less than 35 byte, it will be transferred to a inline method right away, if the method's machine code is less than 325 byte, it could be transferred into a inline method, depending on the jvm.
Real life example:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Then in other classes, I can exit if the code has expired. If I reference the EXPIRED_ON variable from another class, the constant is inline to the byte code, making it very hard to track down all places in the code that checks the expiry date. However, if the other classes invoke the isExpired() method, the actual method is called, meaning a hacker could replace the isExpired method with another which always returns false.
I agree it would be very nice to force a compiler to inline the static final method to all classes which reference it. In that case, you need not even include the Control class, as it would not be needed at runtime.
From my research, this cannot be done. Perhaps some Obfuscator tools can do this, or, you could modify your build process to edit sources before compile.
As for proving if the method from the control class is placed inline to another class during compile, try running the other class without the Control class in the classpath.
so, it seems there arent, but you can use this workaround using guava or an equivalent Function class implementation, because that class is extremely simple, ex.:
assert false : new com.google.common.base.Function<Void,String>(){
#Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
yes, this is dead code just to exemplify how to create a complex code block (within {}) to do something so specific that shouldnt bother us on creating any method for it, AKA inline!
Java9 has an "Ahead of time" compiler that does several optimizations at compile-time, rather than runtime, which can be seen as inlining.

Categories

Resources