I just found it in the API and would like to see one or two examples along with an explanation what it is good for.
The Proxy trait provides a useful basis for creating delegates, but note that it only provides implementations of the methods in Any (equals, hashCode, and toString). You will have to implement any additional forwarding methods yourself. Proxy is often used with the pimp-my-library pattern:
class RichFoo(val self: Foo) extends Proxy {
def newMethod = "do something cool"
}
object RichFoo {
def apply(foo: Foo) = new RichFoo(foo)
implicit def foo2richFoo(foo: Foo): RichFoo = RichFoo(foo)
implicit def richFoo2foo(richFoo: RichFoo): Foo = richFoo.self
}
The standard library also contains a set of traits that are useful for creating collection proxies (SeqProxy, SetProxy, MapProxy, etc).
Finally, there is a compiler plugin in the scala-incubator (the AutoProxy plugin) that will automatically implement forwarding methods. See also this question.
It looks like you'd use it when you need Haskell's newtype like functionality.
For example, the following Haskell code:
newtype Natural = MakeNatural Integer
deriving (Eq, Show)
may roughly correspond to following Scala code:
case class Natural(value: Int) extends Proxy {
def self = value
}
Related
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
}
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.
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) = ???
}
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'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.