Just looking at Scala Akka and wondering what is the difference between the following object initialisation methods.
system.actorOf(Props[HelloActor], name = "helloactor")
and
system.actorOf(Props(new HelloActor("Fred")), name = "helloactor")
I can understand the second one, Props(new HelloActor()), but what is the first one, Props[HelloActor]? I don't know its name so can't google for it.
Props is a case class with a companion object. In Scala code you will see two major ways people will construct objects. One is with a constructor on a class. Another major way is by calling an apply() method on a companion object.
If you look at the source code of akka.actor.Props you will notice that the companion object has four apply() methods, two of which you are referencing in your code above. At time of writing their signatures are:
def apply[T <: Actor: ClassTag](): Props
def apply[T <: Actor: ClassTag](creator: ⇒ T): Props
As helpful sugar Scala allows you to call an apply method without stating the apply method so in your first example you can rewrite that as Props[HelloActor]() and the compiler inserts the apply() method for you. Next, if a method has no arguments you may omit the parenthesis. So the call becomes Props[HelloActor] as you have pointed out above.
Your second example calls the second apply() method.
As to your question about how does the real HelloActor class get instantiated that is a little more complicated. All of the explicitly defined apply() methods eventually call a special apply() method that is generated by the nature of Props being a case class. This apply calls the constructor on Props which creates an akka.actor.IndirectActorProducer. This class holds many strategies that can be used to instantiate the actor. In your simple case it eventually uses reflection to construct your actor.
Square brackets [] in Scala denote the use of a generic class. Generic classes are classes which take a type as a parameter. The class name between the brackets in the instantiation of a generic class is the argument for that type parameter.
So in your case, the Props class has 1 generic parameter, and the line Props[HelloActor] is providing the type HelloActor as the argument for that generic parameter.
Related
Part I
Suppose I have a type class trait Show[T] { def print(t: T): String } with instances for String and Int. Suppose I have a value whose specific type is known only at runtime:
val x: Any = ...
How do I get the appropriate typeclass instance (at runtime, since we don't know the type statically) and do something with it.
Note that it's inadequate to define a method that literally just gives us the typeclass instance:
def instance(x: Any): Show[_]
Since Show.print requires statically known argument type T we still can't do anything with the result of instance. So really, we need to be able to dynamically dispatch to an already-defined function that uses the instance, such as the following:
def display[T](t: T)(implicit show: Show[T]) = "show: " + show.print(t) + "\n"
So assuming display is defined, how do we invoke display, passing along an appropriate Show instance. I.e. something that invokes display(x) properly.
Miles Sabin accomplishes this here using runtime compilation (Scala eval), as an example of "staging", but with only spare documentation as to what's going on:
https://github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/staging.scala
Can Miles's approach be put into a library? Also, what are the limitations of this approach e.g. with respect to generic types like Seq[T]?
Part II
Now suppose T is bounded by a sealed type (such that it's possible to enumerate all the sub-types):
trait Show[T <: Foo]
sealed trait Foo
case class Alpha(..) extends Foo
case class Beta(..) extends Foo
In this case, can we do it with a macro instead of runtime compilation? And can this functionality be provided in some library?
I mostly care about Scala 2.12, but it's worth mentioning if a solution works in 2.11 or 2.10.
I am a little bit confused using companion objects in scala. When you want to provide multiple constructors, usually you declare a companion object and overload the apply method. But what is the difference between this two ways of doing it?:
case class Node(....)
object Node {
def apply(...) = new Node(....) // 1 way
def apply(...) = Node(...) // second way
}
Almost all examples I've seen use the first form:
When to use companion object factory versus the new keyword
"new" keyword in Scala
http://alvinalexander.com/scala/how-to-create-scala-object-instances-without-new-apply-case-class
But my code seems to work the same using both forms. Does using new keyword only have sense when we have a normal class? (Not a case class)?
When you call
val n = Node(..)
The compiler will expand the code to a Node.apply call. Now, one of these apply methods will internally have to call new in order to create an instance of the type. Case classes provide companion objects with an apply method for you out of the box to allow the shorter syntax.
When you want to provide multiple constructors, usually you declare a companion object and overload the apply method
This is the case for case classes. You can also provide additional auxiliary constructors using this():
class Foo(i: Int) {
def this() {
this(0)
}
}
Note this will not provide the syntax sugar apply does, you'll need to use new.
When you declare a case class. A companion object is generated by the compiler with apply method in it whose implementation creates the object of the case class using new keyword.
So you need not create a companion object again with apply method creating object of the case class using new keyword. This work will be done by the compiler
It's obvious that this doesn't work:
trait A
val a = new A
since traits cannot be instantiated (if we added {} after new A then it would work, since we're creating an anonymous class).
However, this does work, and I don't know why:
trait A
trait B
val a = new A with B
Does the process of linearization automatically create an anonymous class for a base trait or what?
From section 5.1 of the spec:
It is possible to write a list of parents that starts with a trait
reference, e.g. mt1 with ... with mtn. In that case the list of parents
is implicitly extended to include the supertype of mt1 as first parent
type. The new supertype must have at least one constructor that does
not take parameters.
So when you write new A with B and A is a trait, you're actually getting new AnyRef with A with B. I'm not 100% sure why the same transformation isn't applied to new MyTrait, but I'd guess it has something to do with avoiding confusion between traits and classes.
I'm willing how to implement an extensible dispatch mechanism in Scala.
For example:
I have a trait called Sender (with a method 'send') and a bunch of classes that implement that trait (MailSender, IPhoneSender, AndroidSender). On top of them there is a class which implements the same trait but dispatches the message to the above senders depending the type of the message.
I know I can use pattern matching, but my problem with that approach is about extensibility: If someone wants to add another sender (i.e. WindowsPhoneSender), he must add a new case to the pattern matching method (thus breaking the open-closed principle). I don't want developers to modify the library's code, so I need this to be as extensible as possible.
I thought about a chain of responsibility approach (in Java I would do that), but is there a better way in Scala? (My knowledge in Scala is limited, but I know the Scala compiler does a lot of magical things)
Thanks!
It would be clearer if you gave a more concrete use case, but you might be looking for the typeclass pattern:
case class AndoidMessage()
case class WindowsMessage()
trait Sender[M]{
def send(message: M)
}
implicit object AndroidSender extends Sender[AndroidMessage]{...}
implicit object WindowsSender extends Sender[AndroidMessage]{...}
def mySendMethod[M: Sender](message: M) = {
// use the implicit Sender[M] to send the message
}
//AndroidSender is resolved implicitly
mySendMethod(new AndroidMessage())
//third party can define their own message and their own
//implicit sender for it (perhaps in a companion object
//so it's resolved automatically)
case class BeosMessage()
object BeosMessage{
implicit object BMSender extends Sender[BeosMessage]{...}
}
I want to create a method that takes a type parameter, obviously with no parameters on its constructor, and returns a dummy object constructed with that constructor. Basically some kind of factory pattern.
Is that even possible in Scala?
Is that a good idea? Any better pattern if it is not?
Is there a way to achieve this at compile-time only (i.e. without reflection)?
Code example :
trait Model
class A extends Model
class B extends Model
def dummy[T <: Model] = new T // Fails compilation with "class type required but T found"
dummy[A] // Returns an instance of A
dummy[B] // Returns an instance of B
This can be done using ClassManifests, which are designed to overcome erasure:
def dummy[T <: Model : ClassManifest] = classManifest[T].erasure.newInstance
As for doing it at compile time without reflection, I guess that it could be done using scala 2.10 macros.