Several IO interface constructors of the Sodor processor collection implements its own clone method. I looked into the usage of clone method in Scala but still cannot figure out why exactly that is done. (I could not find any explicit usage of these methods anywhere in the design)
Sodor is still currently still on Chisel 2. clone was renamed to cloneType in Chisel 3 to distinguish it from clone in Java and Scala. cloneType is generally required by Chisel in order to instantiate new instances of parameterized Bundles. For example:
class MyBundle extends Bundle {
val foo = UInt(32.W)
}
class MyParameterizedBundle(width: Int) extends Bundle {
val bar = UInt(width.W)
}
Chisel often needs to create an instance of a given Bundle class from another instance of that class. Chisel uses Java reflection to do this. If there are no arguments to the constructor then it can just instantiate the object from the default constructor. However, it cannot determine the value of width from an instance of MyParameterizedBundle via reflection, so it cannot provide an appropriate parameter to the constructor. This is what the cloneType function is for. It tells Chisel how to create a new instance of a Bundle from a given object.
We hope to fix this wart in the future, but have not had the time to implement it. The most promising way is to automatically generate cloneType via Scala macro annotations.
Related
In Java, we write .class (for example: String.class) to get information about the given class. In Kotlin you can write ::class or ::class.java. What is the difference between them?
By using ::class, you get an instance of KClass. It is Kotlin Reflection API, that can handle Kotlin features like properties, data classes, etc.
By using ::class.java, you get an instance of Class. It is Java Reflection API, that interops with any Java reflection code, but can't work with some Kotlin features.
First you need to understand about Reflection. According to the docs:
Reflection is a set of language and library features that allows for introspecting the structure of your own program at runtime.
In simple words, it gives you the ability to get the code you have written i.e., the class name you have defined, the function name you have defined, etc. Everything you have written, you can access all these at runtime using Reflection.
::class and ::class.java are basic features of Reflection.
::class gives you a KClass<T> reference and ::class.java gives you Class<T> reference.
Example,
val a = MyClass::class
can be interpreted as
val a = KClass<MyClass>()
Note: Above code is not syntactically correct, because KClass is an interface and interfaces cannot be instantiated. It is just to give you an idea.
A Class<T> class gives you information about the metadata of the T class like interfaces it is implementing, its functions' names, its package name, etc.
KClass is similar to Class but it gives information about some more properties(Kotlin related properties) than Class. All the information a KClass<T> reference can give you about the T class are listed here https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/#properties
According to the Kotlin documentation, when we create an object using any class type as below the reference type will be type of KClass.
val c = MyClass::class // reference type of KClass
Kotlin class reference is not the same as a Java class reference. To get a Java class reference, use the .java property on a KClass instance.
val c = MyClass::class.java // reference type of Class Java
I am using Intellij 14 and in the module settings, there is an option to export dependencies.
I noticed when I write objects that extend traits, I need to select exportin the module settings when other modules try to use these objects.
For example,
object SomeObj extends FileIO
would require me to export the FileIO dependency.
However, if I write a companion class that creates a new instance when the object is called, the exporting is no longer necessary.
object SomeObject {
private val someObject = new SomeObject()
def apply() = someObject
}
private[objectPkg] class SomeObject() extends FileIO {}
This code is more verbose and kind of a hack to the singleton pattern for Scala. Is it good to export third party dependencies with your module? If not, is my pattern the typical solution with Scala?
It all deal with code design principles in general. Basically, if you may switch underlying third party library later, or you system must be flexible to be ported over some other libs - then hiding implementation behind some facade is a must.
Often there is a ready-made set of interfaces in java/scala, which are implemented in third-party and you may just use those ones as a part of your facade to the rest of the system, and overall it is a java way. If this is not the case - you will need to derive interfaces by yourself. The worthiness of this everyone estimates by oneself in context.
As per your case: keep in mind that in java/scala you export names, and if you will just use your class (which extends FileIO) in any way outside your defining code, this means that class is accessible publicly and its type is exported/leaked outside as well. Scala should throw compile error, if some private class escapes its visibility scope (so in your second version of SomeObject it may be the case).
Consider this example: I use typesafe config library often in my applications. It has convenient methods, but I typically leave the space for possible separation (or rather my own extension):
package object config {
object Config {
private val conf: TypeSafeConfig = ConfigFactory.load()
def toTypeSafeConfig: TypeSafeConfig = conf
}
#inline implicit def confToTypeSafeConfig(conf: Config.type): TypeSafeConfig = conf.toTypeSafeConfig
}
Implicit conversion just allows me to call all TypeSafeConfig methods on my Config, and it has a bunch of convenient methods. Theoretically in future I could remove my implicit and implement methods I used right in the Config object. But I can hardly imagine why I would spend the time on this, though. This is some example of leaked implementation, that I don't consider problematic.
I have a class XmlRecord. This class will deal with reading/writing to an xml file. At the moment, I have the following for that class:
class XmlRecord {
private val _file = new File("file.xml")
}
I want this class to somehow create the file if it doesn't exist. I know how to achieve this but I'm unsure how to design it in an Object Orientated way. I think I have two options:
Do I add a code to the constructor (or a call to a private method) that will create this file automatically if it doesn't exist. My problem with this method is that how do I unit test this as this code is effectively private code? Would I have to inject the File dependency so it could be mocked during testing?
Do I get the constructor to return an exception or implement a public method for the class so that the caller can use it to check if a file needs to be created? If so, the caller would then call another public method that would create the file. Again I think I would need to inject the dependency.
I hope that makes sense. I'm just trying to get a better grasp on designing my classes.
The presence of abstractions to accomplish DIP have other design
implications in an Object Oriented program:
All member variables in a class must be interfaces or abstracts.
All concrete class packages must connect only through interface/abstract classes packages.
No class should derive from a concrete class.
No method should override an implemented method.[5]
All variable instantiation requires the implementation of a Creational pattern as the Factory Method or the Factory pattern, or the more complex use of a Dependency Injection framework.
Dependency inversion principle
In Eclipse plugin, I could create scala Object, APP and class. But what's the difference among these 3. Basically, for object, I implement def main(...), then I could run it. But in class, it seems it is similar to normal Java class, but what's the meaning scala APP, it creates a object which extends APP. What's this meant for?
In the JVM, the starting point of the application is a static method main(String[] args), in some class given to the JVM.
In scala there is no static methods, the equivalent is to put a method in an object (as opposed to class). Putting your main method in a class will not work, it is the same as not marking the method static in java.
App is a helper that allows not to write the main method, and put the code directly in the object body.
object MyApp extends App {
doStuff
}
does the same thing as
object MyApp {
def main(args: Array[String]) {doStuff}
}
(arguments can be used in doStuff under the name args)
Scala has no static methods, so public static void main is not available for classes.
Objects are single entries that better fits the "common to every object of a class" scope. So, oversimplifying things, you can think of Object as a Singleton which "acts as an only-static container" (quote from Scala for Java Refugees). If you think about it, that's the perfect place for a main method, and that's why they are declared there.
The App trait just explores the fact that instructions written inside the body of an Object are executed as part of its initialization. It couples this standard behaviour with some delayed initialization tricks to use the body of an object as the main method. So, you can think about it as a short alternative syntax to create a application entry point. It replaced the naive Application trait that had a lot of shortcomings.
Which one of the two to use is really a matter of taste, but I tend to stick with the more familiar main method syntax.
Cheers,
Suppose MyClass is a class defined in Java, and has many static as well as non-static members. I tried to alias this class (and associated companion object) in a Scala object MyObject as shown below:
object MyObject {
import javastuff._
type MyAlias = MyClass
val MyAlias = MyClass
}
Scalac complains:
error: object MyClass is not a value
val MyAlias = MyClass
How do I work around this? Thanks.
Although this works in pure Scala for a class + companion object, it's not possible with Java's static methods, as these don't belong to any interface.
Scala could, in theory, create an object containing delegates to all the static methods of some class, but it doesn't do this currently. It's also possible to write a compiler plugin for this if you feel comfortable writing plugins.
Failing that, you'll either have to create an object full of delegates yourself, or just cherry-pick a few methods and pass them around as functions.
it's not possible with Java's static methods, as these don't belong to any interface.
Update 5 years later: PR 5131 mentions:
We used to disable generation of static forwarders when a object had a
trait as a companion, as one could not add methods with bodies to an
interface in JVM 6.
The JVM lifted this restriction to support default methods in interfaces,
so we can lift the restriction on static forwarders, too.
Fixes scala-dev issue 59
See commit 41c9a17 by Jason Zaugg (retronym).