What are stackable modifications? - scala

I've been reading a book about Scala and there's mention of stackable modifications using traits. What are stackable modifications and for what purposes are they meant to be used?

The fundamental quality which distinguishes stackable modifications (as the terminology is used in scala anyway) is that "super" is influenced dynamically based on how the trait is mixed in, whereas in general super is a statically determined target.
If you write
abstract class Bar { def bar(x: Int): Int }
class Foo extends Bar { def bar(x: Int) = x }
then for Foo "super" will always be Bar.
If you write
trait Foo1 extends Foo { abstract override def bar(x: Int) = x + super.bar(x) }
Then for that method super remains unknown until the class is made.
trait Foo2 extends Foo { abstract override def bar(x: Int) = x * super.bar(x) }
scala> (new Foo with Foo2 with Foo1).bar(5)
res0: Int = 30
scala> (new Foo with Foo1 with Foo2).bar(5)
res1: Int = 50
Why is this interesting? An illustrative example might be some data which you want to compress, encrypt, and digitally sign. You might want to compress then encrypt then sign, or you might want to encrypt then sign then compress, etc. If you design your components in this way, you can instantiate a customized object with exactly the bits you want organized the way you want.

I looked at Real-World Scala presentation where the term stackable modifications is also used. Apparently it's traits that call the super method when overriding, essentially adding functionality and not replacing it. So you accumulate functionality with traits, and it can be used where in Java we often use aspects. Trait plays the role of an aspect, overriding the "interesting" methods and adding the specific functionality such as logging etc. and then calling super and "passing the ball" to the next trait in the chain. HTH.

Related

Proper use of Scala traits and case objects

Trying to get the hang of Scala classes and traits, here's a simple example. I want to define a class which specifies a variety of operations, that could be implemented in lots of ways. I might start with,
sealed trait Operations{
def add
def multiply
}
So for example, I might instantiate this class with an object does that add and multiply very sensibly,
case object CorrectOperations extends Operations{
def add(a:Double,b:Double)= a+b
def multiply(a:Double,b:Double)= a*b
}
And also, there could be other ways of defining those operations, such as this obviously wrong way,
case object SillyOperations extends Operations{
def add(a:Double,b:Double)= a + b - 10
def multiply(a:Double,b:Double)= a/b
}
I would like to pass such an instance into a function that will execute the operations in a particular way.
def doOperations(a:Double,b:Double, op:operations) = {
op.multiply(a,b) - op.add(a,b)
}
I would like doOperations to take any object of type operations so that I can make use of the add and multiply, whatever they may be.
What do I need to change about doOperations, and what am I misunderstanding here? Thanks
Haven't ran your code, but I suppose you got a compilation error.
If you don't define the signature of the methods in the Operations trait, then by default it will be interpreted as () => Unit.
This means that the methods in the inheriting objects are not really overriding the methods in the trait, but define overloads instead. See more about that here. You can verify this by writing override in front of the method definitions in the object methods. That will force the compiler to explicitly warn you that the methods are not overriding anything from the ancestor trait, and works as a "safety net" against similar mistakes.
To fix the bug, spell out the signature of the trait like the following:
sealed trait Operations{
def add(a:Double,b:Double):Double
def multiply(a:Double,b:Double):Double
}
In fact, the output parameter types are not even necessary in the methods of the inheriting objects (but note the added override attributes):
case object CorrectOperations extends Operations{
override def add(a:Double,b:Double) = a+b
override def multiply(a:Double,b:Double) = a*b
}

Where would "abstract override" in subtrait with no implementation be useful, if any?

Given the following example of two traits with one extending another with no implementation of def a in each:
scala> trait A { def a: String }
defined trait A
scala> trait B extends A { abstract override def a: String }
defined trait B
Is the construct useful at all? What are the use cases?
I think the answer is essentially the same as the one linked in your comment. In Scala, the abstract keyword for methods isn't required, since the compiler can figure out whether it's abstract or not based on whether or not it has an implementation. So it's usage here is superfluous.
The override keyword is also not required for methods that are implementing an abstract method (or I guess not doing anything at all, in this case). So really, B is equivalent to:
trait B extends A { def a: String }
Or really just (since B will be assumed to be abstract):
trait B extends A
Similarly to the linked answer, I can imagine once scenario where using override might be useful for readability. If I were making the return type of a in B more specific than A, I could use override as a hint that I'm modifying the behavior in some way:
trait A {
def a: Any
}
trait B extends A {
override def a: String
}
In this case, I'm hinting that a in B might be slightly different than the inherited signature from A. Of course, this is only useful if it's known to the reader and used in a consistent manner. But I could still do the same thing without the override.
Short answer: abstract override is not useful in this case. It's basically like giving a type annotation where none would be needed.
The value added use of abstract override is for decorating an implementation that will be mixed in later, sometimes known as the "stackable trait pattern". See Why is "abstract override" required not "override" alone in subtrait?.
Abstract override indicates that you wish to override an 'abstract' method. Others address why it's useless here, so I'll focus on an example. Abstract override is best used for mixins. A simple example would be a Pollable trait:
trait Pollable{def poll:Double}
Lets say we want to weight this pollable. This trait will be a mixin for our trait. Our weighted pollable will have a weight field, which it will multiply a poll by to get a result. For example:
class OnePollable extends Pollable{
def poll:Double=1
}
val myWeightedOne=new OnePollable with WeightedPollable;
Lets try and write this trait:
//Does not compile
trait WeightedPollable extends Pollable{
var weight=1
def poll:Double=super.poll*weight
}
If you look, you'll see clearly why this doesn't work. Our trait tries to call a super type method that isn't implemented! One solution is to add a default to the super trait, Pollable:
//Don't do this!
trait Pollable{def poll:Double=1}
This sorta works here, but is sorta dumb in a lot of real world applications. The better way is this:
trait WeightedPollable extends Pollable{
var weight=1
abstract override def poll:Double=super.poll*weight
}
It's our friend the abstract override modifier! This tells the compiler that we are overriding an abstract method, but we want to use super to refer to an object we are being mixed into. This also disallows the trait being used as an interface.

Scala pass-through wrappers

Very many times, I'll want to "replace" a single method of a given object.
foo: Foo
foo.bar(i) // original
foo.baz(s) // replace this implementation
I'll wind up creating a pass-through wrapper class.
class FooWrapper(foo: Foo) extends Foo {
def bar(i: Int) = foo.bar(i)
def baz(s: String) = foo.baz(s)
}
And then
foo: Foo
val foo2 = new FooWrapper(foo) { def baz(s: String) = ... }
foo2.bar(i)
foo2.baz(s)
This works with traits and classes, and works without modifying the source code of the type.
I use this quite a bit, particularly when adapting libraries or other bits of code.
This can get tedious with lots of methods. The other day, I wanted to replace the shutdown method on an ExecutorService instance, and I had to do this for a dozen methods.
Is this a common idiom, or is this normally done another way? I suspect this could be done nicely with a macro, though I haven't found any existing ones that do this.
You can achieve that with AOP (Aspect-oriented programming)
There're many libraries to do so, try this one -
https://github.com/adamw/scala-macro-aop
Note that this library is in POC stage for now so you might look for something more mature. I've put it here because I think it shows the concept very clearly.
For your example you'll have to do something like
class FooWrapper(#delegate wrapped: Foo) extends Foo {
def baz(i: Int) = ???
}

Scala Objects and the rise of singletons

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
}

Implementing '.clone' in Scala

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.