First. Consider the following code
scala> val fail = (x: Any) => { throw new RuntimeException }
fail: Any => Nothing = <function1>
scala> List(1).foreach(fail)
java.lang.RuntimeException
at $anonfun$1.apply(<console>:7)
at $anonfun$1.apply(<console>:7)
at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
There is additional anonfun between foreach and exception. One is expected to be a value of fail itself (object of a class Function1[]), but where is the second comes from?
foreach signature takes this function:
def foreach[U](f: A => U): Unit
So, what is the purpose of the second one?
Second, consider the following code:
scala> def outer() {
| def innerFail(x: Any) = { throw new RuntimeException("inner fail") }
|
| Set(1) foreach innerFail
| }
outer: ()Unit
scala> outer()
java.lang.RuntimeException: inner fail
at .innerFail$1(<console>:8)
at $anonfun$outer$1.apply(<console>:10)
at $anonfun$outer$1.apply(<console>:10)
at scala.collection.immutable.Set$Set1.foreach(Set.scala:86)
There are two additional anonfuns... do they really needed? :-E
Let's look at the bytecode.
object ExtraClosure {
val fail = (x: Any) => { throw new RuntimeException }
List(1).foreach(fail)
}
We find, inside the (single) anonymous function:
public final scala.runtime.Nothing$ apply(java.lang.Object);
Code:
0: new #15; //class java/lang/RuntimeException
3: dup
4: invokespecial #19; //Method java/lang/RuntimeException."<init>":()V
7: athrow
public final java.lang.Object apply(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: invokevirtual #27; //Method apply:(Ljava/lang/Object;)Lscala/runtime/Nothing$;
5: athrow
So it's actually not an extra closure after all. We have one method overloaded with two different return values (which is perfectly okay for the JVM since it treats the type of all parameters as part of the function signature). Function is generic, so it has to take the object return, but the code you wrote returns specifically Nothing, it also creates a method that returns the type you'd expect.
There are various ways around this, but none are without their flaws. This is the type of thing that JVMs are pretty good at eliding, however, so I wouldn't worry about it too much.
Edit: And of course in your second example, you used a def, and the anonfun is the class that wraps that def in a function object. That is of course needed since foreach takes a Function1. You have to generate that Function1 somehow.
Related
Suppose I have a function that accepts a object and a list:
case class Point(x: Int, y: Int)
def f1(w: Point, l: List[String]) = { /* do something /* }
I would typically use it like this:
val w = Point(1,1)
val lst = List("Hello", "world")
f1(w, lst) // non empty list
Many times I would need to call the function with empty list as second parameter:
f1(w, List()) // empty list
f1(w, Nil) // empty list
Is there any performance difference between the last two lines ?
I think using List() will invoke List.apply() method. Does Scala compiler optimize it to Nil?
EDIT1
This is not a duplicate of Scala: Nil vs List()
NOTE: Is there any performance difference between Nil vs List() ? Does Scala compiler do any optimizations here?
With a class like this
import collections.immutable.List
class Test {
val l = List() // or Nil
}
Compiling both of them and then checking the generated bytecode with javap -v
List() gives:
5: getstatic #26 // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
8: putfield #14 // Field l:Lscala/collection/immutable/List;
And Nil gives:
5: getstatic #24 // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
8: putfield #13 // Field l:Lscala/collection/immutable/Nil$;
So, the bytecode (and the performance) is the same for both. There might be other reasons to chose one over the other though, as described in the issue linked by Govind in the comments.
A deeper dive into the rabbit hole:
Looking at the sources List() is the sugar for List.apply() which is implemented like this:
def apply[A](xs: A*) = xs.toList
toList comes from TraversableOnce and calls to[List] which implicitly takes a CanBuildFrom[Nothing, A, List[A]], which in this case will be List.canBuildFrom, which in turn comes from ReusableCBF, that builder will then be called with .apply(), ++= the empty array, and then build()
How this can be eliminated/transformed into a getstatic for List() isn't very clear to me. (Or i missed something clever on the way).
I'd like to have a method like
def retrieve[T](value: Option[T])(implicit ct: ClassTag[T]): T;
Inside this method I need to call a Java method (beyond my control) to create an instance of T that requires Class[T]:
public <T> T construct(clazz: Class<T> /* other arguments */) { ... }
How can I get Class[T] from ClassTag[T]? First I thought I could use runtimeClass from ClassTag, but it's type is Class[_], not Class[T]. Or is there any other implicit value that compiler can automatically provide, from which I can obtain Class[T]?
Here is the ticket on getClass and the linked forum discussion in which Odersky speculates:
You could also use a cast.
Here is the duplicate ticket where getClass is fixed. 5.getClass also casts:
/** Return the class object representing an unboxed value type,
* e.g. classOf[int], not classOf[java.lang.Integer]. The compiler
* rewrites expressions like 5.getClass to come here.
*/
def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] =
classTag[T].runtimeClass.asInstanceOf[jClass[T]]
The limitation is reminiscent of this question about pattern matching with ClassTag, in which our naive expectations are also not met.
Does the resistance to Class[A] represent the impedance mismatch between Scala types and the platform?
Given the class type, all one can really do is newInstance. But reflective invocation with a constructor mirror won't give me my type back.
scala> res24 reflectConstructor res25.asMethod
res27: reflect.runtime.universe.MethodMirror = constructor mirror for Bar.<init>(): Bar (bound to null)
scala> res27()
res28: Any = Bar#2eeb08d9
scala> bar.getClass.newInstance
res29: Bar = Bar#31512f0a
scala> classOf[Bar].newInstance
res30: Bar = Bar#2bc1d89f
That doesn't seem fair.
As that mailing thread from 2008 concludes, you expect to use fewer casts in Scala.
BTW, it's not that I disbelieved the code comment, but:
scala> 5.getClass
res38: Class[Int] = int
scala> :javap -
Size 1285 bytes
MD5 checksum a30a28543087238b563fb1983d7d139b
Compiled from "<console>"
[snip]
9: getstatic #27 // Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
12: iconst_5
13: invokestatic #33 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
16: getstatic #38 // Field scala/reflect/ClassTag$.MODULE$:Lscala/reflect/ClassTag$;
19: invokevirtual #42 // Method scala/reflect/ClassTag$.Int:()Lscala/reflect/ClassTag;
22: invokevirtual #46 // Method scala/runtime/ScalaRunTime$.anyValClass:(Ljava/lang/Object;Lscala/reflect/ClassTag;)Ljava/lang/Class;
25: putfield #18 // Field res38:Ljava/lang/Class;
28: return
For performance and safety I would like to implement a fixed-size vector which is both immutable and specialized (I need fast arithmetics). My first idea was to use the #specialized annotation (because I need both integers and reals).
Here is a first try:
package so
class Vec[#specialized A] private[so] ( ary: Array[A] ) {
def apply( i: Int ) = ary(i)
}
However, when I analyze the resulting bytecode with javap, I can see that the elements are still boxed. For instance:
public double apply$mcD$sp(int);
Code:
0: aload_0
1: iload_1
2: invokevirtual #33; //Method apply:(I)Ljava/lang/Object;
5: invokestatic #83; //Method scala/runtime/BoxesRunTime.unboxToDouble:(Ljava/lang/Object;)D
8: dreturn
It looks like arrays are not specialized which seems silly, because arrays are specialized on the JVM.
Is there something I can still do to reach my goal ?
You are likely looking at the code compiled to Vec.class. According to this thread the specialization occurs in subclasses. This can be verified in the REPL:
scala> class Vec[#specialized A] ( ary: Array[A] ) {
| def apply( i: Int ) = ary(i)
| }
defined class Vec
scala> new Vec( Array[Int](1) ).getClass
res0: java.lang.Class[_ <: Vec[Int]] = class Vec$mcI$sp
As you can see for Int it is using the subclass Vec$mcI$sp. And if you run javap on that class you will see that it is infact specializing the code properly. This is what the apply method looks like in Vec$mcI$sp.class using javap:
public int apply(int);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: iload_1
2: invokevirtual #13 // Method apply$mcI$sp:(I)I
5: ireturn
Which I suppose is what you want when using Int.
Is there a way in scala to get the arguments back from a already partially applied function?
Does this even make sense, should be done, or fits into any use case?
example:
def doStuff(lower:Int,upper:Int,b:String)=
for(turn <- lower to upper) println(turn +": "+b)
Imagine that at one point I know the 'lower' argument and I get a function of applying it to 'doStuff'
val lowerDoStuff = doStuff(3,_:Int,_:String)
Is there a way for me to get that 3 back ?
(for the sake of example, imagine that I am inside a function which only received 'lowerDoStuff' and now needs to know the first argument)
Idiomatic scala is prefered to introspection/reflection (if possible).
Idiomatic Scala: no, you can't. You have specifically said that the first argument is no longer relevant. If the compiler can make it disappear entirely, that's best: you say you have a function that depends on an int and a string, and you haven't made any promises about what generated it. If you really need that value, but you also really need to pass a 2-argument function, you can do it by hand:
class Function2From3[A,B,C,Z](f: (A,B,C) => Z, val _1: A) extends Function2[B,C,Z] {
def apply(b: B, c: C) = f(_1, b, c)
}
val lowerDoStuff = new Function2From3(doStuff _, 3)
Now when you get the function later on, you can pattern match to see if it's a Function2From3, and then read the value:
val f: Function2[Int,String,Unit] = lowerDoStuff
f match {
case g: Function2From3[_,_,_,_] => println("I know there's a "+g._1+" in there!")
case _ => println("It's all Greek to me.")
}
(if it's important to you that it be an integer, you can remove A as a generic parameter and make _1 be an integer--and maybe just call it lower while you're at it).
Reflection: no, you can't (not in general). The compiler's smarter than that. The generated bytecode (if we wrap your code in class FuncApp) is:
public final void apply(int, java.lang.String);
Signature: (ILjava/lang/String;)V
Code:
0: aload_0
1: getfield #18; //Field $outer:LFuncApp;
4: iconst_3
5: iload_1
6: aload_2
7: invokevirtual #24; //Method FuncApp.doStuff:(IILjava/lang/String;)V
10: return
Notice the iconst_3? That's where your 3 went--it disappeared into the bytecode. There's not even a hidden private field containing the value any more.
As I read, Scala immutable val doesn't get translated to Java final for various reasons. Does this mean that accessing a val from an other Thread must be guarded with synchronization in order to guarantee visibility?
the assignment to val itself is fine from a multi-threading point of view, because you have to assign val a value when you declare it and that value can't be changed in the future (so if you do a val s="hello", s is "hello" from its birth on: no thread will ever read another value).
There are a couple of caveats, however:
1 - if you assign an instance of a mutable class to val, val by itself will not "protect" the internal state of the class from changing.
class Foo(s:String) { var thisIsMutable=s }
// you can then do this
val x = new Foo("hello")
x.thisIsMutable="goodbye"
// note that val guarantees that x is still the same instance of Foo
// reassigning x = new Foo("goodbye") would be illegal
2 - you (or one of your libraries...) can change a val via reflection. If this happens two threads could indeed read a different value for your val
import java.lang.reflect.Field
class Foo { val foo=true } // foo is immutable
object test {
def main(args: Array[String]) {
val f = new Foo
println("foo is " + f.foo) // "foo is true"
val fld = f.getClass.getDeclaredField("foo")
fld.setAccessible(true)
fld.setBoolean(f, false)
println("foo is " + f.foo) // "foo is false"
}
}
As object members, once initialized, vals never change their values during the lifetime of the object. As such, their values are guaranteed to be visible to all threads provided that the reference to the object didn't escape in the constructor. And, in fact, they get Java final modifiers as illustrated below:
object Obj {
val r = 1
def foo {
val a = 1
def bar = a
bar
}
}
Using javap:
...
private final int r;
...
public void foo();
...
0: iconst_1
1: istore_1
2: aload_0
3: iload_1
4: invokespecial #31; //Method bar$1:(I)I
7: pop
...
private final int bar$1(int);
...
0: iload_1
1: ireturn
...
As method locals, they are used only within the method, or they're being passed to a nested method or a closure as arguments (see lifted bar$1 above). A closure might be passed on to another thread, but it will only have a final field with the value of the local val. Therefore, they are visible from the point where they are created to all other threads and synchronization is not necessary.
Note that this says nothing about the object the val points to - it itself may be mutable and warrant synchronization.
In most cases the above cannot be violated via reflection - the Scala val member declaration actually generates a getter with the same name and a private field which the getter accesses. Trying to use reflection to modify the field will result in the NoSuchFieldException. The only way you could modify it is to add a specialized annotation to your class which will make the specialized fields protected, hence accessible to reflection. I cannot currently think of any other situation that could change something declared as val...