Hve a look to the following code snippet:
trait T { def y = println("hello") }
class A {
self: T =>
def x = y
}
abstract class B {
val self: T
def x = self.y
}
val a = new A with T
val b = new B with T {
val self = this
}
a.x
b.x
Class A and B have a reference to trait T, A has a self reference and B
is using composition.
I see only two differences here: The first is in creating new objects
and the second in accessing T.
In B there is more syntactic sugar, I don't need to explicitly access
reference self and I don't need to bind the variable.
Are there another differences and are there some situations in which one
should preferred instead of the other?
Your question seems to excludes plain inheritance. For A, the self type has no advantage compared to class A extends T. For B, if you intend to create it only as written, that is with self = this, extends is just as good too (and so much simpler)
I don't think there are that many use case for self type (but this is not a discussion of composition vs inheritance)
One of them is to force a trait to be instanciated only as a subtype of another type not yet known, because it appears as a type parameter or an abstract type member. For instance, trait X[A] {self: A => ...} You can have a look at this realistic example on the scala site, with a type member.
Another is when you are composing modules, rather than instances, in particular when module have type members, making composition feasible only at compile time. This is more or less related to the CakePattern.
Composition (whether with abstract val or constructor parameter) has of course the strong advantage that you can pass an external instance of T, share it between different instances of B, choose it much more dynamically. instances may be passed to and returned from functions, mixins cannot
In scala, I only use composition when I must "mix" a class in another one. In your example,
if T was a class:
class T { def y = println("hello") }
then new X with T would not be possible.
Related
Here is a simplification of my scenario that I am trying to make it work
// the UnrelatedN are mostly used as tag traits, for type-checking purposes
trait Unrelated1
trait Unrelated2
trait HasUnrelatedSupertrait {
type Unrelated // abstract type
}
trait HasUnrelated[... /*TODO: Parametrize with (factory of) UnrelatedN*/]
extends HasUnrelatedSupertrait {
type Unrelated = UnrelatedType // path-dependent type
implicit val unrelated = ... // instantiate or access (singleton) instance of Unrelated
}
trait Subtype1 extends HasUnrelated[/* Something involving Unrelated1 */] with ...
trait Subtype2 extends HasUnrelated[/* Something involving Unrelated2 */] with ...
// ... (many more similar subtypes)
Basically, I would like to inject the implicit val instance of
abstract type into (subtypes of) HasUnrelated in a non-intrusive
way, hopefully through a type parameter that I have some flexibility
over (see TODO).
(I don't care if Unrelated1/2 instances are constructed via new,
factory and how those factories are defined (as objects, classes
etc.), as long as I can get 2 distinct instances of Unrelated1/2.)
Some of the constraining factors why my attempts have failed are:
HasUnrelated and HasUnrelatedSupertrait must be traits, not classes
traits cannot have parameters (so I cannot pass (implicit) val factory)
traits cannot have context or view bounds (to bring in ClassTag/TypeTag)
I am not willing to clutter all the subtypes of HasUnrelated with
additional type/val declarations
However, I am willing to do one or more of the following changes:
introduce (singleton) factories for Unrelated1/2
introduce arbitrary inheritance in Unrelated1/2 as long as those
types are still unrelated (neither is subtype of the other)
add supertype to HasUnrelated as long is it requires extra
declarations (if any) only in HasUnrelated, but not any of its subtypes
Is there a way to achieve this in Scala and if so how?
Probably type class is something you are looking for? Consider this example
trait Companion[T] {
val comp: T
}
object Companion {
def apply[T: Companion] = implicitly[Companion[T]]
}
object UnrelatedType {
implicit val thisComp =
new Companion[UnrelatedType.type] {
val comp = UnrelatedType
}
}
// Somewhere later
type Unrelated = UnrelatedType
implicit val unrelated = Companion[UnrelatedType]
I have the following setup:
trait A
{
def doSomething(): Unit;
}
object B extends A
{
override def doSomething(): Unit =
{
// Implementation
}
}
class B(creator: String) extends A
{
override def doSomething(): Unit =
{
B.doSomething() // Now this is just completely unnecessary, but the compiler of course insists upon implementing the method
}
}
Now you may wonder why I even do this, why I let the class extend the trait as well.
The problem is, that somewhere in the Program there is a Collection of A.
So somewhere:
private val aList: ListBuffer[A] = new ListBuffer[A]
and in there, I also have to put Bs (among other derivates, namely C and D)
So I can't just let the B-class not extend it.
As the implementation is the same for all instances, I want to use an Object.
But there is also a reason I really need this Object. Because there is a class:
abstract class Worker
{
def getAType(): A
def do(): Unit =
{
getAType().doSomething()
}
}
class WorkerA
{
def getAType(): A =
{
return B
}
}
Here the singleton/object of B gets returned. This is needed for the implementation of do() in the Worker.
To summarize:
The object B is needed because of the generic implementation in do() (Worker-Class) and also because doSomething() never changes.
The class B is needed because in the collection of the BaseType A there are different instances of B with different authors.
As both the object and the class have to implement the trait for above reasons I'm in kind of a dilemma here. I couldn't find a satisfying solution that looks neater.
So, my question is (It turns out as a non-native-speaker I should've clarified this more)
Is there any way to let a class extend a trait (or class) and say that any abstract-method implementation should be looked up in the object instead of the class, so that I must only implement "doSomething()" (from the trait) once (in the object)? As I said, the trait fulfills two different tasks here.
One being a BaseType so that the collection can get instances of the class. The other being a contract to ensure the doSomething()-method is there in every object.
So the Object B needs to extend the trait, because a trait is like a Java interface and every (!) Object B (or C, or D) needs to have that method. (So the only option I see -> define an interface/trait and make sure the method is there)
edit: In case anyone wonders. How I really solved the problem: I implemented two traits.
Now for one class (where I need it) I extend both and for the other I only extend one. So I actually never have to implement any method that is not absolutely necessary :)
As I wrote in the comment section, it's really unclear to me what you're asking.
However, looking at your code examples, it seems to me that trait A isn't really required.
You can use the types that already come with the Scala SDK:
object B extends (()=>Unit) {
def apply() { /* implementation */ }
}
Or, as a variant:
object B {
val aType:()=>Unit = {() => /* implementation */ }
}
In the first case, you can access the singleton instance with B, in the second case with B.aType.
In the second case, no explicit declaration of the apply method is needed.
Pick what you like.
The essential message is: You don't need a trait if you just define one simple method.
That's what Scala functions are for.
The list type might look like this:
private val aList:ListBuffer[()=>Unit] = ???
(By the way: Why not declare it as Seq[()=>Unit]? Is it important to the caller that it is a ListBuffer and not some other kind of sequence?)
Your worker might then look like this:
abstract class Worker {
def aType:()=>Unit // no need for the `get` prefix here, or the empty parameter list
def do() {aType()}
}
Note that now the Worker type has become a class that offers a method that invokes a function.
So, there is really no need to have a Worker class.
You can just take the function (aType) directly and invoke it, just so.
If you always want to call the implementation in object B, well - just do that then.
There is no need to wrap the call in instances of other types.
Your example class B just forwards the call to the B object, which is really unnecessary.
There is no need to even create an instance of B.
It does have the private member variable creator, but since it's never used, it will never be accessed in any way.
So, I would recommend to completely remove the class B.
All you need is the type ()=>Unit, which is exactly what you need: A function that takes no parameters and returns nothing.
If you get tired of writing ()=>Unit all the time, you can define a type alias, for example inside the package object.
Here is my recommentation:
type SideEffect = ()=>Unit
Then you can use SideEffect as an alias for ()=>Unit.
That's all I can make of it.
It looks to me that this is probably not what you were looking for.
But maybe this will help you a little bit along the way.
If you want to have a more concrete answer, it would be nice if you would clarify the question.
object B doesn't really have much to do with class B aside from some special rules.
If you wish to reuse that doSomething method you should just reuse the implementation from the object:
class B {
def doSomething() = B.doSomething()
}
If you want to specify object B as a specific instance of class B then you should do the following:
object B extends B("some particular creator") {
...
}
You also do not need override modifiers although they can be handy for compiler checks.
The notion of a companion object extending a trait is useful for defining behavior associated with the class itself (e.g. static methods) as opposed to instances of the class. In other words, it allows your static methods to implement interfaces. Here's an example:
import java.nio.ByteBuffer
// a trait to be implemented by the companion object of a class
// to convey the fixed size of any instance of that class
trait Sized { def size: Int }
// create a buffer based on the size information provided by the
// companion object
def createBuffer(sized: Sized): ByteBuffer = ByteBuffer.allocate(sized.size)
class MyClass(x: Long) {
def writeTo(buffer: ByteBuffer) { buffer.putLong(x) }
}
object MyClass extends Sized {
def size = java.lang.Long.SIZE / java.lang.Byte.SIZE
}
// create a buffer with correct sizing for MyClass whose companion
// object implements Sized. Note that we don't need an instance
// of MyClass to obtain sizing information.
val buf = createBuffer(MyClass)
// write an instance of MyClass to the buffer.
val c = new MyClass(42)
c.writeTo(buf)
General style question.
As I become better at writing functional code, more of my methods are becoming pure functions. I find that lots of my "classes" (in the loose sense of a container of code) are becoming state free. Therefore I make them objects instead of classes as there is no need to instantiate them.
Now in the Java world, having a class full of "static" methods would seem rather odd, and is generally only used for "helper" classes, like you see with Guava and Commons-* and so on.
So my question is, in the Scala world, is having lots of logic inside "objects" and not "classes" quite normal, or is there another preferred idiom.
As you mention in your title, objects are singleton classes, not classes with static methods as you mention in the text of your question.
And there are a few things that make scala objects better than both static AND singletons in java-world, so it is quite "normal" to use them in scala.
For one thing, unlike static methods, object methods are polymorphic, so you can easily inject objects as dependencies:
scala> trait Quack {def quack="quack"}
defined trait Quack
scala> class Duck extends Quack
defined class Duck
scala> object Quacker extends Quack {override def quack="QUAACK"}
defined module Quacker
// MakeItQuack expects something implementing Quack
scala> def MakeItQuack(q: Quack) = q.quack
MakeItQuack: (q: Quack)java.lang.String
// ...it can be a class
scala> MakeItQuack(new Duck)
res0: java.lang.String = quack
// ...or it can be an object
scala> MakeItQuack(Quacker)
res1: java.lang.String = QUAACK
This makes them usable without tight coupling and without promoting global state (which are two of the issues generally attributed to both static methods and singletons).
Then there's the fact that they do away with all the boilerplate that makes singletons so ugly and unidiomatic-looking in java. This is an often overlooked point, in my opinion, and part of what makes singletons so frowned upon in java even when they are stateless and not used as global state.
Also, the boilerplate you have to repeat in all java singletons gives the class two responsibilities: ensuring there's only one instance of itself and doing whatever it's supposed to do. The fact that scala has a declarative way of specifying that something is a singleton relieves the class and the programmer from breaking the single responsibility principle. In scala you know an object is a singleton and you can just reason about what it does.
You can also use package objects e.g. take a look at the scala.math package object here
https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_1_final/src//library/scala/math/package.scala
Yes, I would say it is normal.
For most of my classes I create a companion object to handle some initialization/validation logic there. For example instead of throwing an exception if validation of parameters fails in a constructor it is possible to return an Option or an Either in the companion objects apply-method:
class X(val x: Int) {
require(x >= 0)
}
// ==>
object X {
def apply(x: Int): Option[X] =
if (x < 0) None else Some(new X(x))
}
class X private (val x: Int)
In the companion object one can add a lot of additional logic, such as a cache for immutable objects.
objects are also good for sending signals between instances if there is no need to also send messages:
object X {
def doSomething(s: String) = ???
}
case class C(s: String)
class A extends Actor {
var calculateLater: String = ""
def receive = {
case X => X.doSomething(s)
case C(s) => calculateLater = s
}
}
Another use case for objects is to reduce the scope of elements:
// traits with lots of members
trait A
trait B
trait C
trait Trait {
def validate(s: String) = {
import validator._
// use logic of validator
}
private object validator extends A with B with C {
// all members of A, B and C are visible here
}
}
class Class extends Trait {
// no unnecessary members and name conflicts here
}
I'm trying to figure out how to .clone my own objects, in Scala.
This is for a simulation so mutable state is a must, and from that arises the whole need for cloning. I'll clone a whole state structure before moving the simulation time ahead.
This is my current try:
abstract trait Cloneable[A] {
// Seems we cannot declare the prototype of a copy constructor
//protected def this(o: A) // to be defined by the class itself
def myClone= new A(this)
}
class S(var x: String) extends Cloneable[S] {
def this(o:S)= this(o.x) // for 'Cloneable'
def toString= x
}
object TestX {
val s1= new S("say, aaa")
println( s1.myClone )
}
a. Why does the above not compile. Gives:
error: class type required but A found
def myClone= new A(this)
^
b. Is there a way to declare the copy constructor (def this(o:A)) in the trait, so that classes using the trait would be shown to need to provide one.
c. Is there any benefit from saying abstract trait?
Finally, is there a way better, standard solution for all this?
I've looked into Java cloning. Does not seem to be for this. Also Scala copy is not - it's only for case classes and they shouldn't have mutable state.
Thanks for help and any opinions.
Traits can't define constructors (and I don't think abstract has any effect on a trait).
Is there any reason it needs to use a copy constructor rather than just implementing a clone method? It might be possible to get out of having to declare the [A] type on the class, but I've at least declared a self type so the compiler will make sure that the type matches the class.
trait DeepCloneable[A] { self: A =>
def deepClone: A
}
class Egg(size: Int) extends DeepCloneable[Egg] {
def deepClone = new Egg(size)
}
object Main extends App {
val e = new Egg(3)
println(e)
println(e.deepClone)
}
http://ideone.com/CS9HTW
It would suggest a typeclass based approach. With this it is possible to also let existing classes be cloneable:
class Foo(var x: Int)
trait Copyable[A] {
def copy(a: A): A
}
implicit object FooCloneable extends Copyable[Foo] {
def copy(foo: Foo) = new Foo(foo.x)
}
implicit def any2Copyable[A: Copyable](a: A) = new {
def copy = implicitly[Copyable[A]].copy(a)
}
scala> val x = new Foo(2)
x: Foo = Foo#8d86328
scala> val y = x.copy
y: Foo = Foo#245e7588
scala> x eq y
res2: Boolean = false
a. When you define a type parameter like the A it gets erased after the compilation phase.
This means that the compiler uses type parameters to check that you use the correct types, but the resulting bytecode retains no information of A.
This also implies that you cannot use A as a real class in code but only as a "type reference", because at runtime this information is lost.
b & c. traits cannot define constructor parameters or auxiliary constructors by definition, they're also abstract by definition.
What you can do is define a trait body that gets called upon instantiation of the concrete implementation
One alternative solution is to define a Cloneable typeclass. For more on this you can find lots of blogs on the subject, but I have no suggestion for a specific one.
scalaz has a huge part built using this pattern, maybe you can find inspiration there: you can look at Order, Equal or Show to get the gist of it.
I'm creating some parameterized classes C[T] and I want to make some requirements of the characteristics of the type T to be able to be a parameter of my class. It would be simple if I just wanted to say that T inherited from traits or classes (as we do with Ordering). But I want it to implement some functions as well.
For example, I've seen that many pre-defined types implement MinValue and MaxValue, I would like my type T to implement these too. I've received some advice to just define an implicit function. But I wouldn't like that all the users were obliged to implement this function for these when it is already implemented. I could implement them at my code too, but it seems just to be a poor quick fix.
For example, when defining heaps, I would like to allowd users to construct a empty Heap. In these cases I want to inicialize value with the minimum value the type T could have. Obviously this code does not works.
class Heap[T](val value:T,val heaps:List[Heap[T]]){
def this()=this(T.MinValue,List())
}
I also would love to receive some advice about really good online Scala 2.8 references.
A bunch of things, all loosely related by virtue of sharing a few methods (though with different return types). Sure sounds like ad-hoc polymorphism to me!
roll on the type class...
class HasMinMax[T] {
def maxValue: T
def minValue: T
}
implicit object IntHasMinMax extends HasMinMax[Int] {
def maxValue = Int.MaxValue
def minValue = Int.MinValue
}
implicit object DoubleHasMinMax extends HasMinMax[Double] {
def maxValue = Double.MaxValue
def minValue = Double.MinValue
}
// etc
class C[T : HasMinMax](param : T) {
val bounds = implicitly[HasMinMax[T]]
// now use bounds.minValue or bounds.minValue as required
}
UPDATE
The [T : HasMinMax] notation is a context bound, and is syntactic sugar for:
class C[T](param : T)(implicit bounds: HasMinMax[T]) {
// now use bounds.minValue or bounds.minValue as required
}
You can either use type bounds:
trait Base
class C[T <: Base]
enabling C to be parametrized with any type T which is a subtype of Base.
Or you can use implicit parameters to express requirements:
trait Requirement[T] {
def requiredFunctionExample(t: T): T
}
class C[T](implicit req: Requirement[T])
Thus, objects of class C can only be constructed if there exists an implementation of the Requirement trait for the type T you wish to parametrize them with. You can place implementations of Requirement for different types T in, for instance, a package object, thus bringing them into scope whenever the corresponding package is imported.