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)
Related
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.
To clarify: I am NOT asking what I can use a Singleton design pattern for. The question is about largely undocumented trait provided in scala.
What is this trait for? The only concrete use case I could find so far was to limit a trait to objects only, as seen in this question: Restricting a trait to objects?
This question sheds some light on the issue Is scala.Singleton pure compiler fiction?, but clearly there was another use case as well!
Is there some obvious use that I can't think of, or is it just mainly compiler magicks?
I think the question is answered by Martin Odersky's comment on the mailing list thread linked to from the linked question:
The type Singleton is essentially an encoding trick for existentials
with values. I.e.
T forSome { val x: T }
is turned into
[x.type := X] T forSome { type X <: T with Singleton }
Singleton types are usually not used directly…
In other words, there is no intended use beyond guiding the typer phase of the compiler. The Scala Language Specification has this bit in §3.2.10, also §3.2.1 indicates that this trait might be used by the compiler to declare that a type is stable.
You can also see this with the following (Scala 2.11):
(new {}).isInstanceOf[Singleton]
<console>:54: warning: fruitless type test: a value of type AnyRef cannot also
be a Singleton
(new {}).isInstanceOf[Singleton]
^
res27: Boolean = true
So you cannot even use that trait in a meaningful test.
(This is not a definite answer, just my observation)
everyone . Please forgive me asking a stupid question on Scala.
Though I have been programming in Scala for about 2 years, I still find it hard to understand implicit usage. Let's take an example for discussion:
Array(1,2,3,4).map(x => x)
If you look up the scaladoc, you cant' find the method map on Array class. The reason that map can apply on Array(1,2,3,4) is that there is an implicit function implicit def intArrayOps (xs: Array[Int]): ArrayOps[Int] defined in scala.Predef.
However, there are two parameter lists, where the second one is written as implicit bf: CanBuildFrom[Array[T], B, That]). Now I wonder where the compiler finds a proper argument for type CanBuildFrom when applying map on Array(1,2,3,4).
The implicit resolution includes searching the companion object for the type of the implicit parameter as well as the companion objects for the type parameters of the implicit parameter. In the example above the signature of map is the following
def map[B, That](f: (Int) => B)(implicit bf: CanBuildFrom[Array[Int], B, That]): That
Since we have no type requirements for That we can ignore it for now. After we look in the local and container scopes and find no matching implicits, the next place to look for an implicit would be the companion object for CanBuildFrom. However it has no companion object. So we continue on and look in Array for an implicit. We find one in the form of
implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Array[_], T, Array[T]]
Since we have no type requirements and a matching implicit, "That" is forced to be of type Array[Int] and completes our typing.
This question is partially answered with other question on StackOverflow. Let me give a try to summarize them:
The first part you need to know is where the Scala compiler looks for implicits. You can find some more detail about CanBuildFrom here.
If you have understood what is mentioned in the answers about implicits ‣you should take a look to the construction of Scala Collections. Their inheritance-hierarchy is explained here and for List here. All of them are build up with Builders. This is explained in detail in a question about breakOut.
To round up your knowledge, you should know how to pimp the Collections. Also, this is explained on StackOverflow in this question.
Please note, the best answers on StackOverflow are summarized in the Scala-Tag-Wiki.
I want to come out a way to define a new method in some existing class in scala.
For example, I think the asInstanceOf[T] method has too long a name, I want to replace it with as[T].
A straight forward approach can be:
class WrappedAny(val a: Any) {
def as[T] = a.asInstanceOf[T]
}
implicit def wrappingAny(a: Any): WrappedAny = new WrappedAny(a)
Is there a more natural way with less code?
Also, a strange thing happens when I try this:
scala> class A
defined class A
scala> implicit def toA(x: Any): A = x
toA: (x: Any)A
scala> toA(1)
And the console hang. It seems that toA(Any) should not pass the type checking phase, and it can't when it's not implicit. And putting all the code into a external source code can produce the same problem. How did this happen? Is it a bug of the compiler(version 2.8.0)?
There's nothing technically wrong with your approach to pimping Any, although I think it's generally ill-advised. Likewise, there's a reason asInstanceOf and isInstanceOf are so verbosely named; it's to discourage you from using them! There's almost certainly a better, statically type-safe way to do whatever you're trying to do.
Regarding the example which causes your console to hang: the declared type of toA is Any => A, yet you've defined its result as x, which has type Any, not A. How can this possibly compile? Well, remember that when an apparent type error occurs, the compiler looks around for any available implicit conversions to resolve the problem. In this case, it needs an implicit conversion Any => A... and finds one: toA! So the reason toA type checks is because the compiler is implicitly redefining it as:
implicit def toA(x: Any): A = toA(x)
... which of course results in infinite recursion when you try to use it.
In your second example you are passing Any to a function that must return A. However it never returns A but the same Any you passed in. The compiler then tries to apply the implicit conversion which in turn does not return an A but Any, and so on.
If you define toA as not being implicit you get:
scala> def toA(x: Any): A = x
<console>:6: error: type mismatch;
found : Any
required: A
def toA(x: Any): A = x
^
As it happens, this has been discussed on Scala lists before. The pimp my class pattern is indeed a bit verbose for what it does, and, perhaps, there might be a way to clean the syntax without introducing new keywords.
The bit about new keywords is that one of Scala goals is to make the language scalable through libraries, instead of turning the language into a giant quilt of ideas that passed someone's criteria for "useful enough to add to the language" and, at the same time, making other ideas impossible because they weren't deemed useful and/or common enough.
Anyway, nothing so far has come up, and I haven't heard that there is any work in progress towards that goal. You are welcome to join the community through its mailing lists and contribute to its development.
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.