I'm new in Kotlin and trying to convert an app written in Scala to Kotlin. In Scala there is the ListBuffer from scala.collection.mutable.ListBuffer. Is there an equivalent in Kotlin? I tried importing com.sun.tools.javac.util.ListBuffer but I would get an error when I try to compile: Kotlin: Symbol is declared in module 'jdk.compiler' which does not export package 'com.sun.tools.javac.util'?
In Kotlin you can use MutableList instead for the same purposes. Though I should note that Scala and Kotlin collections are very different in general, e.g. Kotlin prefers read-only collections to actually immutable ones and doesn't have a direct equivalent of Scala List. So if you are hoping to take a Scala library/app and change class names, it won't work unless your app is very trivial.
Related
I am getting this error in IntelliJ:
object breakOut is not a member of package collection
import scala.collection.{breakOut, mutable}
Can you suggest me which package I should add or if the can share the code for breakOut class maybe defining it will work ?
breakOut was in the Scala standard library until Scala 2.13. You shouldn't need to depend on any additional libraries. In Scala 2.13 and later, you should remove that parameter and explicitly convert to the required type, e. g. using toList, toMap, toSet or whatever it is that's required.
I'm still a bit confused about the scala Shapeless library after reading many articles. It seems that Shapeless uses scala compiling features? So does it use reflection and is it safe for production code?
Shapeless doesn't use reflection, it uses macros to inspect the structure of classes. With Shapeless this inspection happens at compilation time and not runtime (reflection happens at runtime). As a result of this Shapeless can be considered safer than reflection because it will be able to make many checks at compilation time.
Let's try to get a field by name using shapeless
case class MyClass(field: String)
import shapeless._
val myClassLens = lens[MyClass] >> 'field
val res = myClassLens.get(MyClass("value")) // res == "value"
if we use an invalid field name the compiler will complain with a compilation error
On the other hand if we tried to achieve this same thing using reflection the field name would be checked at runtime (maybe in production), that's why reflection is not considered as safe as Shapeless. It will also be way faster with Shapeless than reflection
class Wish{
val s = "Hello! User. Wish you a Great day."
}
object Wish{
def main(args: Array[String]){
val w = new Wish()
println("Value - " + w.s )
}
}
Java classes can be used in Scala. Similarly, can Scala classes be used in Java?
Yes, Scala classes can be called from Java and vice versa.
The below text is taken from: Scala FAQs
What does it mean that Scala is compatible with Java?
The standard Scala backend is a Java VM. Scala classes are Java classes, and vice versa. You can call the methods of either language from methods in the other one. You can extend Java classes in Scala, and vice versa. The main limitation is that some Scala features do not have equivalents in Java, for example traits.
The following post also could be helpful to you: how to call Scala from Java
Yes. If you want to do this, there are a few things you might want to remember:
Do not use operators in your method names or provide a wordy alternative. Operator names can be called from Java but are mangled into somethings very ugly.
Java users might expect Java style getters and setters. You can produce those automatically by adding #BeanProperty annotation to fields.
In the same way Java user might be accustomed to factory methods called ClassName.of where Scala uses .apply. Those you have to provide by hand, if you want to provide that service.
So I'm playing with writing a battlecode player in Scala. In battlecode certain classes are disallowed and there is a runtime exception if you ever try to access them. When I use the Array.fill function I get a message from the battlecode server saying [java] Illegal class: scala/reflect/Manifest$. This is the offending line:
val g_score = Array.fill[Int](rc.getMapWidth(), rc.getMapHeight())(0)
The method takes an implicit ClassManifest argument which has the following documentation:
A ClassManifest[T] is an opaque descriptor for type T. It is used by the compiler
to preserve information necessary for instantiating Arrays in those cases where
the element type is unknown at compile time.
But I do know the type of the array elements at compile time, as shown above I explicitly state that they will be Int. Is there a way to avoid this? To workaround I've written my own version of Array.fill. This seems like a hack. As an aside, does Scala have real 2D arrays? Array.fill seems to return an Array[Array[T]] which is the only way I found to write my own. This also seems inelegant.
Edit: Using Scala 2.9.1
For background information, see this related question: What is a Manifest in Scala and when do you need it?. In this answer, you will find an explanation why manifests are needed for arrays.
In short: Although the JVM uses type erasure, arrays are an exception and need a manifest. Since you could compile your code, that manifest was found (manifests are always available for proper types). Your error occurs at runtime.
I don't know the details of the battlecode server, but there are two possibilities: Either you are running your compiled classes with a binary incompatible version of Scala (difference in major version, e.g. compiled with Scala 2.9 and server uses 2.10). Or the server doesn't even have the scala-library.jar on its class path.
As said in the comment, manifests are deprecated in Scala 2.10 and replaced by ClassTag.
EDIT: So it seems the class loader is artificially restricting the allowed classes. My suggestion would be: Add a helper Java class. You can easily mix Java and Scala code. If it's just about the Int-Array instantiation, you could provide something like:
public static class Helper {
public static int[][] makeArray(int d1, int d2) { return new int[d1][d2](); }
}
(hope that's valid java code, a bit rusty)
Also, have you tried to create the outer array with new Array[Array[Int]](d1), and then iterate to create the inner arrays?
I'm using Groovy for testing and Scala for actual code. Obviously I often use Scala's collection types - but when I generate test data in Groovy I often use the java.util.*-types.
I started writing static conversion methods based on the scalaj-collection library. But that's just not 'groovy'.
What's the best approach to convert one to the other?
Might implicit conversions work somehow?
UPDATE:
For example if I wouldn't manually convert the types I of course get:
groovy.lang.MissingMethodException:
No signature of method: static setup is applicable for argument types: (java.util.ArrayList)
Possible solutions: setup(scala.collection.immutable.List)
Did you try the "built-in" implicit conversions?
import scala.collection.JavaConversions._
Another approach is to change your Scala code to use Java collection types when declaring parameters and rely on implicit conversions in the method body to get the benefit of Scala collections operations.