What is a Manifest in Scala and when do you need it? - scala

Since Scala 2.7.2 there is something called Manifest which is a workaround for Java's type erasure. But how does Manifest work exactly and why / when do you need to use it?
The blog post Manifests: Reified Types by Jorge Ortiz explains some of it, but it doesn't explain how to use it together with context bounds.
Also, what is ClassManifest, what's the difference with Manifest?
I have some code (part of a larger program, can't easily include it here) that has some warnings with regard to type erasure; I suspect I can solve these by using manifests, but I'm not sure exactly how.

The compiler knows more information about types than the JVM runtime can easily represent. A Manifest is a way for the compiler to send an inter-dimensional message to the code at runtime about the type information that was lost.
It isn't clear if a Manifest would benefit the errors you are seeing without knowing more detail.
One common use of Manifests is to have your code behave differently based on the static type of a collection. For example, what if you wanted to treat a List[String] differently from other types of a List:
def foo[T](x: List[T])(implicit m: Manifest[T]) = {
if (m <:< manifest[String])
println("Hey, this list is full of strings")
else
println("Non-stringy list")
}
foo(List("one", "two")) // Hey, this list is full of strings
foo(List(1, 2)) // Non-stringy list
foo(List("one", 2)) // Non-stringy list
A reflection-based solution to this would probably involve inspecting each element of the list.
A context bound seems most suited to using type-classes in scala, and is well explained here by Debasish Ghosh:
http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-i.html
Context bounds can also just make the method signatures more readable. For example, the above function could be re-written using context bounds like so:
def foo[T: Manifest](x: List[T]) = {
if (manifest[T] <:< manifest[String])
println("Hey, this list is full of strings")
else
println("Non-stringy list")
}

A Manifest was intended to reify generic types that get type-erased to run on the JVM (which does not support generics). However, they had some serious issues: they were too simplistic, and were unable to fully support Scala's type system. They were thus deprecated in Scala 2.10, and are replaced with TypeTags (which are essentially what the Scala compiler itself uses to represent types, and therefore fully support Scala types). For more details on the difference, see:
Scala: What is a TypeTag and how do I use it?
How do the new Scala TypeTags improve the (deprecated) Manifests?
In other words
when do you need it?
Before 2013-01-04, when Scala 2.10 was released.

Not a complete answer, but regarding the difference between Manifest and ClassManifest, you can find an example in the Scala 2.8 Array paper:
The only remaining question is how to implement generic array creation. Unlike Java, Scala allows an instance creation new Array[T] where T is a type parameter. How can this be implemented, given the fact that there does not exist a uniform array representation in Java?
The only way to do this is to require additional runtime information which describes the type T. Scala 2.8 has a new mechanism for this, which is called a Manifest. An object of type Manifest[T] provides complete information about the type T.
Manifest values are typically passed in implicit parameters; and the compiler knows how to construct them for statically known types T.
There exists also a weaker form named ClassManifest which can be constructed from knowing just the top-level class of a type, without necessarily knowing all its argument types.
It is this type of runtime information that’s required for array creation.
Example:
One needs to provide this information by passing a ClassManifest[T] into the
method as an implicit parameter:
def tabulate[T](len:Int, f:Int=>T)(implicit m:ClassManifest[T]) = {
val xs = new Array[T](len)
for (i <- 0 until len) xs(i) = f(i)
xs
}
As a shorthand form, a context bound1 can be used on the type parameter T instead,
(See this SO question for illustration)
, giving:
def tabulate[T: ClassManifest](len:Int, f:Int=>T) = {
val xs = new Array[T](len)
for (i <- 0 until len) xs(i) = f(i)
xs
}
When calling tabulate on a type such as Int, or String, or List[T], the Scala compiler can create a class manifest to pass as implicit argument to tabulate.

Let's also chck out manifest in scala sources (Manifest.scala), we see:
Manifest.scala:
def manifest[T](implicit m: Manifest[T]) = m
So with regards to following example code:
def foo[A](somelist: List[A])(implicit m: Manifest[A]): String = {
if (m <:< manifest[String]) {
"its a string"
} else {
"its not a string"
}
}
we can see that the manifest function searches for an implicit m: Manifest[T] which satisfies the type parameter you provide in our example code it was manifest[String]. So when you call something like:
if (m <:< manifest[String]) {
you are checking if the current implicit m which you defined in your function is of type manifest[String] and as the manifest is a function of type manifest[T] it would search for a specific manifest[String] and it would find if there is such an implicit.

Related

What is ClassManifest in Scala?

I am new to Scala and I was learning "context bound" from posts. But I found many of those are explaining "context bound" using ClassManifest as example. For instance,
def tabulate[T](len: Int, f: Int => T)(implicit m: ClassManifest[T]) = {
val xs = new Array[T](len)
for (i <- 0 until len) xs(i) = f(i)
xs
}
I find it weird that the implicit parameter m is required but never used in the function body. Thus I would like to know what ClassManifest is and what its relationship is with context bound. Thanks!
EDIT:
I have seen What is a Manifest in Scala and when do you need it? before, but it's asking for Manifest not ClassManifest, and there is no explanation regarding ClassManifest in that post, thus I ask this similar (but, IMO, not duplicate) question.
You can find explanation about ClassManifest for old scala versions (before 2.10) here. Please, read all answers, some of them explain not only Manifest but ClassManifest too:
There exists also a weaker form named ClassManifest which can be
constructed from knowing just the top-level class of a type, without
necessarily knowing all its argument types.
In Scala 2.11.8, 2.12-M4 ClassManifest is deprecated and became an alias to ClassTag :
type ClassManifest[T] = ClassTag[T]
It's deprecated since 2.10.0.
P.S. Actually this post from scala documentation that you probably read is completely outdated, even the view bounds (<%) described there are deprecated too (for a quite long time) so you should avoid them as well (using this simple trick if you really need them, but implicit views are not recommended in any form)

What is the reasoning for the imbalance of Scala's regular value assignment vs extractor assignment?

Scala appears to have different semantics for regular value assignment versus assignment during an extraction. This has created some very subtle runtime bugs for me as my codebase has migrated over time.
To illustrate:
case class Foo(s: String)
def anyRef(): AnyRef = { ... }
val Foo(x) = anyRef() // compiles but throws exception if anyRef() is not a Foo
val f: Foo = anyRef() // does not compile
I don't see why the two val assignment lines would be imbalanced with regard to compile/runtime behavior.
Some I am curious: Is there a reason for this behavior? Is it an undesirable artifact of the way the extraction is implemented?
(tested in Scala 2.11.7)
Yes, there is.
In the case of an extractor you are specifying a pattern that you expect to match at this position. This is translated to a call of an extractor method from Any to Option[String] and this method can be called with the value of type AnyRef you provide. You are just asserting, that you do indeed get a result and not "None".
In the other line you are using a type annotation, i.e. you are specifying the type of "f" explicitly. But then you are assigning an incompatible value.
Of course the compiler could add implicit type casts but making type casts so easy would not really suit a language like Scala.
You should also keep in mind that extractors have nothing to do with types. In the Pattern Foo(x) the name Foo has nothing to do with the type Foo. It is just the Name of an extractor method.
Using patterns in this way is of course a quite dynamic feature, but I think it is intentional.

Why do we have to explicitly specify the ClassTag typeclass

Now that scala has iterated towards a JVM type erasure fix with the ClassTag typeclass, why is it an opt-in, rather than having the compiler always capture the type signature for runtime inspection. Having it an implicit parametrized type constraint would make it possible to call classTag[T] regardless of the generic parameter declaration.
EDIT: I should clarify that I don't mean that scala should change the signature behind the scenes to always inlcude ClassTag. Rather I mean that since ClassTag shows that scala can capture runtime Type information and therefore avoid type erasure limitations, why can't that capture be implicit as part of the compiler so that that information is always available in scala code?
My suspicion is that it's backwards compatibility, java ecosystem compatibility, binary size or runtime overhead related, but those are just speculation.
Backwards compatibility would be completely destroyed, really. If you have a simple method like:
def foo[A](a: A)(implicit something: SomeType) = ???
Then suppose that in the next version of Scala, the compiler suddenly added implicit ClassTags to the signature of all methods with type parameters. This method would be broken. Anywhere it was being explicitly called like foo(a)(someTypeValue) wouldn't work anymore. Binary and source compatibility would be gone.
Java interoperability would be ugly. Supposing our method now looks like this:
def foo[A : ClassTag](a: A) = ???
Because ClassTags are generated by the Scala compiler, using this method from Java would prove more difficult. You'd have to create the ClassTag yourself.
ClassTag<MyClass> tag = scala.reflect.ClassTag$.MODULE$.apply(MyClass.class);
foo(a, tag);
My Java might not be 100% correct, but you get the idea. Anything parameterized would become very ugly. Well, it already is if it requires an implicit ClassTag, but the class of methods where this would be necessary would increase dramatically.
Moreover, type erasure isn't that much of a problem in most parameterized methods we (I, at least) use. I think automatically requiring a ClassTag for each type parameter would be far more trouble than it would help, for the above reasons.
Certainly this would add more compiler overhead, as it would need to generate more ClassTags than it usually would. I don't think it would add much more runtime overhead unless the ClassTag makes a difference. For example, in a simple method like below, the ClassTag doesn't really do anything:
def foo[A : ClassTag](a: A): A = a
We should also note that they're not perfect, either. So adding them isn't an end-all solution to erasure problems.
val list = List(1, "abc", List(1, 2, 3), List("a", "b"))
def find[A: ClassTag](l: List[Any]): Option[A] =
l collectFirst { case a: A => a }
scala> find[List[String]]
res2: Option[List[String]] = Some(List(1, 2, 3)) // Not quite! And no warnings, either.
Adding a ClassTag to every single class instance would add overhead, and surely also break compatibility. It's also in many places not possible. We can't just infuse java.lang.String with a ClassTag. Furthermore, we'd still be just as susceptible to erasure. Having a ClassTag field in each class is really no better than using getClass. We could make comparisons like
case a if(a.getClass == classOf[String]) => a.asInstanceOf[String]
But this is horribly ugly, requires a cast, and isn't necessarily what the ClassTag is meant to fix. If I tried something like this with my find method, it wouldn't work--at all.
// Can't compile
def find[A](l: List[Any]): Option[A] =
l collectFirst { case a if(a.getClass == classOf[A]) => a.asInstanceOf[A] }
Even if I were to fashion this to somehow work with ClassTag, where would it come from? I could not say a.classTag == classTag[A], because A has already been erased. I need the ClassTag at the method call site.
Yes, you would penalise any generic method or class for a use case that is quite seldom (e.g. requiring array construction or heterogeneous map value recovery). With this idea of "always class tags" you would also effectively destroy the possibility to call Scala code from Java. In summery, it simply doesn't make any sense to require a class tag to be always present, neither from compatibility, performance or class size point of view.

Why do some Scala methods use polymorphic arguments instead of using Any/Nothing?

For example, Exception.allCatch is defined as
def allCatch[T]: Catch[T]
Why not just
val allCatch: Catch[Nothing]
when Catch is covariant in its argument?
Or, why PartialFunction object defines
def empty[A, B]: PartialFunction[A, B]
instead of just
val empty: PartialFunction[Any,Nothing]
?
Update: So far it seems that the answers miss the point. So please include a specific examples in your answer that really target the question. For example: Show a piece of code that works with def empty[A, B]: PartialFunction[A, B] but doesn't work (or is less convenient) with val empty: PartialFunction[Any,Nothing].
This saves the need for casting later and allows to treat the args type as T instead of Any, which is usually more convenient.
Here is an example:
scala> def func1[T](arg : T) : T = { arg }
func1: [T](arg : T)T
scala> def func2(arg : Any) : Any = { arg }
func2: (arg: Any)Any
scala> func1(4)
res4: Int = 4
scala> func2(4)
res7: Any = 4
Looking at the source of PartialFunction available here we can see that it in fact calls a private method on the PartialFunction object:
private[this] val empty_pf: PartialFunction[Any, Nothing]
So the return type of empty will always be PartialFunction[Any, Nothing]. As for the reasoning behind I have no idea. Maybe someone else have better insight as to why. You could try the language mailing list as well...
If you hard-code the type, like PartialFunction[Any,Nothing], you cannot restrict your function to take a more specific parameter than Any.
By using a generic type parameter, you can end up with a more flexible satisfying all cases and especially making the function safe.
Let's assume you want a function aiming to take an Animal as parameter and returning an Integer.
Let's assume that function is declared as being:
def myFunction: PartialFunction[Any,Nothing]
Firstly, PartialFunction would not be specialized to Animal at parameter side but to Any. What about if I pass a Human as parameter...., it would pass.. What about safety?
Secondly, If this function is declared as returning Nothing, you can't return from it any value but Nothing! Indeed, Nothing subclasses all classes in Scala.
This leads to the known rule that return type parameter must always be covariant in order to make a function interesting, not the case with Nothing.
In fact, Nothing is interesting only when dealing with the empty method of PartialFunction. Logic since an empty PartialFunction by definition involves nothing to return and should be forced to do it :)
You would ask: "So why don't we change the return type to Any?"
Answer: Because you'd lose all the benefit of generic erasure time making compiler to add needed casts automatically => You wouldn't retrieve directly the Integer value, but Any. annoying..
Actually, it seems that Scala standard library has some more places where generic type parameter is redundant (because of type variance). For example, see my question about foreach. My guess, based on #Peter's answer, is that these redundant generics make the interface more clear. Thanks to them, we don't have to remember which types are covariant, contravariant and invariant. Also, this makes things way simpler for people who are not familiar with variance, which is rather an advanced feature of Scala.

How does the Scala type checker know to prevent calling flatten on a List that is already flat

I'm kind of new to Scala and I have a question about the type system.
The flatten method works on nested collections, so if I have a List of Lists it will flatten it into a List. But it does not make sense to call flatten on a collection that is already flat. And sure enough the Scala type checker will flag that as an error.
List(List(1,2,3),List(4,5,6)).flatten // produces List(1,2,3,4,5,6)
List(1,2,3,4).flatten // type error
I understand that this somehow relies on an implicit parameter to flatten. But I don't know where the implicit value comes from and how it is used to assert the type of the object flatten is called on. Also, why doesn't the implicit parameter show up in the scaladocs for List.flatten?
To understand how this works, we need to have a look at the type signature of flatten:
def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): List[B]
A is the element type of the list and B is the type of the elements of each element. In order for flatten to work, there has to be an implicit conversion from the element types to a GenTraversableOnce[B]. That is only the case for collections or if you implement your own implicit conversion. For example, you could define one for pairs:
implicit def pairToList[A](p:(A,A)) = List(p._1, p._2)
List(1->2,2->3).flatten //compiles! List(1,2,2,3)
The trick is an implicit witness that ensures that the elements in the list are traversable. Here is the (slightly simplified) signature of flatten taken from GenericTraversableTemplate:
def flatten[B](implicit asTraversable: A => TraversableOnce[B])
: GenTraversable[B] =
In your case, the witness cannot be found for elements of type Int, and the invocation of flatten is therefore rejected by the compiler.
If you wanted to make your example compile, you could use the following implicit definition:
implicit def singleToList[A](a: A) = List(a)
(As a side-note: I'd consider such an implicit as quite dangerous, since it's applicability is very general, which can result in unpleasant surprises because the compiler might inject invocations at various places without you being aware of it.)