I'm looking for help on calling the scala compiler in clojure. How would this line translate to clojure?
final G.Run run = g.new Run();
Inner classes in Java are just a syntactic sugar for classes that get passes the outer class reference in their (syntactic) constructor.
I am not aware of any syntactic sugar for calling such constructors in Clojure. But we can examine how this Java language syntactic sugar is translated into generated JVM bytecode.
Let's take this example:
package test;
public class Outer {
public String oName;
public Outer(String name) {
this.oName = name;
}
public class Inner {
public String iName;
public Inner(String name) {
this.iName = name;
}
}
}
When we compile this code and check the generated bytecode we can see the following syntactic constructor has been generated in test.Outer.Inner class (use javap -verbose Outer\$Inner.class command):
public test.Outer$Inner(test.Outer, java.lang.String);
descriptor: (Ltest/Outer;Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=3
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:Ltest/Outer;
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: aload_0
10: aload_2
11: putfield #3 // Field iName:Ljava/lang/String;
14: return
LineNumberTable:
line 12: 0
line 13: 9
line 14: 14
In Java we don't use this constructor directly but a call to it is generated by Java compiler.
So this code in Java:
Outer outer = new Outer("outer");
Outer.Inner inner = outer.new Inner("inner");
is compiled to something like this in JVM bytecode:
Outer outer = new Outer("outer");
Outer.Inner inner = new Outer.Inner(outer, "inner");
We can leverate this in Clojure and translate JVM bytecode version to Clojure code:
(import '[test Outer Outer$Inner])
(let [outer (Outer. "outer")
inner (Outer$Inner. outer "inner")]
(println "Outer" (.-name outer))
(println "Inner" (.-name inner)))
Related
In Kotlin, if we declare a class member as var and nullable type, compiler doesn't allow us to run the member function although we put an if statement before calling the function because the compiler can't guarantee that the member isn't been set to null after checking against null and before calling the method.
But if we are using a safe call compiler approves our code.
My question, how the compiler makes the safe call atomic? Isn't a second thread can change the variable between checking for null and calling the method (eat method in the example)?
Code for first situation:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
if (w != null)
{
w.eat()
}
}
}
class Wolf
{
fun eat() : Unit
println("wolf is eating")
}
Code for second situation:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
w?.eat()
}
}
class Wolf
{
fun eat():Unit
{
//code
}
}
The compiler puts the contents of the field to the local variable and then compares it with null. You can clearly see it if you decompile Kotlin bytecode.
In Kotlin, how costly is the casting of classes?
So for instance, let's have the following Test class
open class Test {
open fun question() = "Basic question"
}
and 3 inheriting classes
class MathTest : Test() {
override fun question() = "2+2=?"
}
class EnglishTest : Test() {
override fun question() = "Who created SO?"
}
class HistoryTest: Test() {
override fun question() = "When was SO created?"
}
How costly would it be to cast (for instance, let's say) 100 Test objects to either one of these 3, at runtime, in Android (and in general) ?
I messed around a little bit with disassembling the generated bytecode, and except for one case, casting is identical to Java. The one case where it seems to be different is when using the safe cast operator, as?, like so:
val thing = "" as? Int
This generates equivalent bytecode to this Java code:
String _temp = "";
if (!(_temp instanceof Integer)) {
_temp = null;
}
Integer thing = (Integer) _temp;
This makes it slightly more expensive than a regular cast in Java. However, there is no direct equivalent to this behavior in Java, short of writing a similar if statement anyways, so I think it's safe to say that casting in Kotlin is no more expensive than casting in Java.
I'm using Google Mock (gMock) for the first time. Given the following code snippet:
class LinkSignals
{
public:
virtual ~LinkSignals() { }
virtual void onLink(std::string) = 0;
virtual void onUnLink() = 0;
};
class MockLinkSignals : public LinkSignals
{
public:
MOCK_METHOD1(onLink, void(std::string));
MOCK_METHOD0(onUnLink, void());
};
MockLinkSignals mock_signals;
When I execute some test code that causes EXPECT_CALL(mock_signals, onLink(_)) to be run how can I inspect the argument to onLink()?
You would normally use either existing gmock matchers or define your own to check the arguments passed to the mock method.
For example, using the default Eq equality matcher:
EXPECT_CALL(mock_signals, onLink("value_I_expect"))
Or check for sub string say:
EXPECT_CALL(mock_signals, onLink(HasSubstr("contains_this")))
The gmock documentation provides details of the standard matchers that are available, and also describes how to make custom matchers, for example for an integer argument type:
MATCHER(IsEven, "") { return (arg % 2) == 0; }
It is possible to capture an argument to a variable by attaching an action to the expectation, although this can have limited use in the scope of the expectation:
EXPECT_CALL(mock_signals, onLink(_)).WillOnce(SaveArg<0>(pointer))
I'd suggest studying the various matchers and actions available before choosing the best approach for your particular case.
Question 1
Is it irrelevant whether a List (list of objects) or a List<String> (list of Strings) is used in Groovy?
In the code example below, both lists end up being an ArrayList (ArrayList of objects). Would have expected the second list to be an ArrayList<String> (ArrayList of Strings).
Does Groovy lose the type information when the class is compiled and infer it when the compiled class is executed?
Example 1
List untypedList = ["a", "b", "c"]
List<String> typedList = ["a", "b", "c"]
println "Untyped list List: ${untypedList.getClass()}"
println "Typed list List<String>: ${typedList.getClass()}"
Output 1
Untyped list List: class java.util.ArrayList
Typed list List<String>: class java.util.ArrayList // Would have expected ArrayList<String>
Question 2
I would have expected the line typedList << new Integer(1) in the example below to fail with an exception because I'm trying to put an int into a list of Strings. Can anyone explain why I can add an int to the String-typed List?
The output shows that it remains an Integer, i.e. it's not on-the-fly converted to a String "1".
Example 2
List untypedList = ["a", "b", "c"]
List<String> typedList = ["a", "b", "c"]
untypedList << new Integer(1)
typedList << new Integer(1) // Why does this work? Shouldn't an exception be thrown?
println "Types:"
println "Untyped list List: ${untypedList.getClass()}"
println "Typed list List<String>: ${typedList.getClass()}"
println "List contents:"
println untypedList
println typedList
println "Untyped list:"
untypedList.each { println it.getClass() }
println "Typed list:"
typedList.each { println it.getClass() }
Output 2
Types:
Untyped list List: class java.util.ArrayList
Typed list List<String>: class java.util.ArrayList
List contents:
[a, b, c, 1]
[a, b, c, 1]
Untyped list:
class java.lang.String
class java.lang.String
class java.lang.String
class java.lang.Integer
Typed list:
class java.lang.String
class java.lang.String
class java.lang.String
class java.lang.Integer
When running Groovy "normally", generics are thrown away before compilation, so only exist in the source as helpful reminders to the developer.
However, you can use #CompileStatic or #TypeChecked to make Groovy honour these Generics and check the types of things at compilation.
As an example, consider I have the following project structure:
project
|---- src
| |---- main
| |---- groovy
| |---- test
| |---- ListDelegate.groovy
| |---- Main.groovy
|---- build.gradle
With the code:
build.gradle
apply plugin: 'groovy'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.2.1'
}
task( runSimple, dependsOn:'classes', type:JavaExec ) {
main = 'test.Main'
classpath = sourceSets.main.runtimeClasspath
}
ListDelegate.groovy
package test
class ListDelegate<T> {
#Delegate List<T> numbers = []
}
Main.groovy
package test
class Main {
static main( args ) {
def del = new ListDelegate<Integer>()
del << 1
del << 'tim'
println del
}
}
Now, running gradle runSimple gives us the output:
:compileJava UP-TO-DATE
:compileGroovy
:processResources UP-TO-DATE
:classes
:runSimple
[1, tim]
BUILD SUCCESSFUL
Total time: 6.644 secs
So as you can see, the generics were thrown away, and it just worked adding Integers and Strings to out List of supposedly only Integers
Now, if we change ListDelegate.groovy to:
package test
import groovy.transform.*
#CompileStatic
class ListDelegate<T> {
#Delegate List<T> numbers = []
}
And run again:
:compileJava UP-TO-DATE
:compileGroovy
:processResources UP-TO-DATE
:classes
:runSimple
[1, tim]
BUILD SUCCESSFUL
Total time: 6.868 secs
We get the same output!! This is because whilst ListDelegate is now statically compiled, our Main class is still dynamic, so still throws away generics before constructing the ListDelegate... So we can also change Main.groovy to:
package test
import groovy.transform.*
#CompileStatic
class Main {
static main( args ) {
def del = new ListDelegate<Integer>()
del << 1
del << 'tim'
println del
}
}
And now re-running gradle runSimple give us:
:compileJava UP-TO-DATE
:compileGroovy
startup failed:
/Users/tyates/Code/Groovy/generics/src/main/groovy/test/Main.groovy: 10:
[Static type checking] - Cannot find matching method test.ListDelegate#leftShift(java.lang.String).
Please check if the declared type is right and if the method exists.
# line 10, column 9.
del << 'tim'
^
1 error
:compileGroovy FAILED
Which is, as you'd expect, failing to add a String to our declared List of Integer.
In fact, you only need to CompileStatic the Main.groovy class and this error will be picked up, but I always like to use it where I can, not just where I need to.
As #tim_yates notes, it is possible to enable compile time checks with the #TypeChecked/#CompileStatic annotations.
Another alternative is to enable runtime type checking by wrapping the collection with Collections.checkedList(). While this doesn't use the generics or the declared type, enforcing it at runtime sometimes fits in better with loosely typed dynamic code. This is a Java platform feature not specific to groovy.
Example:
// no type checking:
list1 = ["a", "b", "c"]
list1 << 1
assert list1 == ["a", "b", "c", 1]
// type checking
list2 = Collections.checkedList(["a", "b", "c"], String)
list2 << 1
// ERROR java.lang.ClassCastException:
// Attempt to insert class java.lang.Integer element into collection with element type class java.lang.String
From Wikipedia, for Java:
Generics are checked at compile-time for type-correctness. The generic
type information is then removed in a process called type
erasure. For example, List will be converted to the
non-generic type List, which ordinarily contains arbitrary objects.
The compile-time check guarantees that the resulting code is
type-correct.
This type information is for compiler and IDE. Groovy is based on Java and inherits same principles for generics.
At other hand, Groovy is more dynamic language, so probably, it's the reason why it doesn't check types on compile time. IMO for Groovy it's some kind of code comment, sometimes very useful.
PS #tim_yates suggested a link to Groovy docs about Generics, that confirms:
Groovy currently does a little further and throws away generics information "at the source level".
See unit test below. An Actor class defined inside and outside of the unit test itself appear to behave differently when being instantiated via via system.actorOf but only when using the Props style recommended in the Akka documentation (page 67, Section 3.1 Props of Akka Scala Documentation, Release 2.2.3).
I declare two simple Greeter Actors, one inside and one outside the spec, and then get ActorRefs for each one in two different ways -- once using the deprecated Props style and once using the recommended Props style. Only line [4] throws the IllegalArgumentException.
Any ideas what might be going on? Thanks for any help!
(Note: same issue arises using FunSpec so WordSpec, MustMatchers don't seem to be a factor)
import org.junit.runner.RunWith
import org.scalatest.WordSpec
import org.scalatest.matchers.MustMatchers
import akka.actor.ActorSystem
import akka.actor.Props
import org.scalatest.junit.JUnitRunner
import akka.actor.Actor
class MyGreeter extends Actor {
def receive = {
case _ => println("greetings!")
}
}
#RunWith(classOf[JUnitRunner])
class HelloAkkaTest extends WordSpec with MustMatchers {
class MyOtherGreeter extends Actor {
def receive = {
case _ => println("greetings!")
}
}
"Greeter" must {
"greet" in {
val system = ActorSystem()
system.actorOf(Props[MyGreeter], "greeter") // [1] Works
system.actorOf(Props(new Greeter)) // [2] Works
system.actorOf(Props(new MyOtherGreeter)) // [3] Works
system.actorOf(Props[MyOtherGreeter], "other") // [4] Fails!
}
}
}
I am using scalatest 2.10-2.0-RC3 with scala 2.10.2 and akka 2.10-2.3.0-RC2
What you face here is an interesting detail of scala and nested classes. When you have a construct like
class Foo {
class Bar
}
then the inner class Bar will be bound to a specific instance of Foo, meaning you can't instantiate it outside of this instance.
scala> new Foo
res5: Foo = Foo#5b2cef50
scala> new res5.Bar
res6: res5.Bar = Foo$Bar#64f8b658
scala> new Foo#Bar
<console>:12: error: Foo is not a legal prefix for a constructor
new Foo#Bar
^
The Props.apply[A <: Actor] implicitly retrieves an instance of ClassTag[A] an then tries to call the constructor through reflection. So let's have a look at the constructors of Foo#Bar:
scala> classOf[Foo#Bar].getConstructors
res9: Array[java.lang.reflect.Constructor[_]] = Array(public Foo$Bar(Foo))
As you can see, it expects an instance of Foo as parameter. So how do we fix this?
My suggestion would be to just take the class outside of the test class. There are 2 possibilities, either put it directly under the package, as your other class, or put in in the companion of the test class.
Another way to fix this would be to pass a reference to the test class to the Props:
system.actorOf(Props(classOf[MyOtherGreeter], this), "other")