What are the compiler generated implicit values in Scala 2.10? - scala

In the Scala reflection guide is written the following:
As with Manifests, one can in effect request that the compiler
generate a TypeTag. This is done by simply specifying an implicit
evidence parameter of type TypeTag[T]. If the compiler fails to find a
matching implicit value during implicit search, it will automatically
generate a TypeTag[T].
This StackOverflow answer beautifully explains the concept of "implicit evidence". However, it is still not completely clear to me what it means that the compiler will
generate a TypeTag[T].
Does this mean that this is a special case of "implicit evidence" search? I.e. the class TypeTag[T] is handled in a special way when the compiler does implicit search ? I tried to look for implicit parameter values in the Scala reflection APIs but I did not find any which provides a TypeTag[T], so I assume the TypeTag[T] implicit parameter is coming from inside the compiler (as the documentation says). So the classname TypeTag[T] is hardcoded into the compiler's source. Is this assumption correct ?
Is the automatic generation of implicit values documented somewhere? In other words, is there a documentation somewhere which lists all the automatically generated implicit evidences ? I did not find TypeTag[T] in the Scala language specification (version 2.9). The closest concept there to TypeTag[T] is Manifest which are automatically generated implicit parameters. Are Manifests the only automatically generated implicit value parameters in Scala 2.9 ?

Yes, TypeTags and WeakTypeTags are treated specially by implicit search. Now that implicit macros actually work, we plan to remove this hardcode, but that remains to be implemented.
So far there's no documentation for automatic generation of implicit values apart from source code, which says that only type tags and manifests are currently generated: https://github.com/scala/scala/blob/38ee986bcad30a8835e8f197112afb5cce2b76c5/src/compiler/scala/tools/nsc/typechecker/Implicits.scala#L1288

Related

Why are implicit conversion deprecated in scala?

Taken from "Scala with cats" (page 18):
Implicit Conversions
When you create a type class instance constructor using an implicit def, be sure to mark the parameters to the method as implicit pa­rameters. Without this keyword, the compiler won’t be able to fill in the parameters during implicit resolution. implicit methods with non‐implicit parameters form a different Scala pattern called an implicit conversion. This is also different from the previous section on Interface Syntax, because in that case the JsonWriter is an implicit class with extension methods. Implicit con­version is an older programming pattern that is frowned upon in mod­ern Scala code. Fortunately, the compiler will warn you when you do this. You have to manually enable implicit conversions by importing scala.language.implicitConversions in your file
Can anyone please sum up well why implicit conversion are deprecated? What were there limit or issues? Why the approach with implicit parameters is better?
Note I know how to use the modern approach well, including chaining implicit and all. I am just curious as to what was the issue and why it was deprecated.
Martin Odersky, the inventor of Scala, has indicated that implicits (and implicit conversions) are being deprecated in scala 3.1 and will eventually be removed from the language altogether.
the implicit functionality will be replaced with Extension Methods and Givens. Extension Methods and Givens provide a more tighter functional solution that doesn't introduce the unsuspecting and hidden side effects that implicits cause. Odersky now views implicits as a “recipe for disaster" and are "too implicit" which was his motivation to replace their functionality in 3.x.
https://www.slideshare.net/Lightbend/scala-3-is-coming-martin-odersky-shares-what-to-know
https://hub.packtpub.com/is-scala-3-0-a-new-language-all-together-martin-odersky-its-designer-says-yes-and-no/

How to Find Available Implicit Conversions for a Given Type in Scala

I am writing an autocompleter (i.e., code completion like in Eclipse or IntelliJ) for a domain specific language that is a subset of Scala. Users frequently use implicit conversions to hide the more advanced features of Scala like options or Scalaz disjunctions.
I am looking for a way, either at compile time or runtime, to acquire a list of implicit conversions available for a receiver (i.e., for the ‘x’ in ‘val y = x.foo’). So, I have two specific questions:
Is there some library that, given the type of a receiver, can find all the implicit conversions that the compiler could use to turn that receiver into another type?*
How is the identification of available implicit conversions actually done by the Scala compiler? I am not sure where in the source to look to find it; some documentation about how the compiler does this or the location in the source where it does it would also be very helpful.
*: As you might have guessed, I plan to use the resulting list to get all the available fields and methods of all the types the given variable could be implicitly converted to so that the autocompleter can suggest them all to users. If there’s an even more direct way to do that, that would be great too.

Is there any style guidelines about using implicit parameter with default value in scala?

Is it fine to use such solutions like here:
def convert[T](x: T)(implicit format = Default) = ...
It allows you to not specify implicits if you don't need to. But many libraries (at least Lift Json and Scala Concurrent) avoid such kind of default implicit values and push user to always specify an implicit. Is there any recommendations about it for library designers?
Retronym said in passing:
https://groups.google.com/d/msg/scala-user/6MudBXELxVQ/ul67d5Rh4b4J
Arguably it is in poor style to define implicit params with defaults
Compare:
implicit parameter VS default parameter value
and here's a good one:
https://stackoverflow.com/a/20016152/1296806

Collision of implicits in Scala

The following Scala code works correctly:
val str1 = "hallo"
val str2 = "huhu"
val zipped: IndexedSeq[(Char, Char)] = str1.zip(str2)
However if I import the implicit method
implicit def stringToNode(str: String): xml.Node = new xml.Text(str)
then the Scala (2.10) compiler shows an error: value zip is not a member of String
It seems that the presence of stringToNode somehow blocks the implicit conversion of str1 and str2 to WrappedString. Why? And is there a way to modify stringToNode such that zip works but stringToNode is still used when I call a function that requires a Node argument with a String?
You have ambiguous implicits here. Both StringOps and xml.Node have the zip-method, therefore the implicit conversion is ambiguous and cannot be resolved. I don't know why it doesn't give a better error message.
Here are some links to back it up:
http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOps
and
http://www.scala-lang.org/api/current/index.html#scala.xml.Node
edit: it was StringOps, not WrappedString, changed the links :) Have a look at Predef: http://www.scala-lang.org/api/current/index.html#scala.Predef$
to see predefined implicits in Scala.
I would avoid using implicits in this case. You want 2 different implicit conversions which both provide a method of the same name (zip). I don't think this is possible. Also, if you import xml.Text, you can convert with just Text(str) which should be concise enough for anyone. If you must have this implicit conversion to xml.Node, I would pack the implicit def into an object and then import it only in the places where you need it to make your code readable and to, possibly, avoid conflicts where you also need to zip strings. But basically, I would very much avoid using implicits just to make convenient conversions.
Like #Felix wrote, it is generally a bad idea to define implicit conversions between similar data types, like the one you used. Doing that weakens type system, leads to ambiguities like you encountered and may produce extremely unclear ("magic") code which is very hard to analyze and debug.
Implicit conversions in Scala are mostly used to define lightweight, short-lived wrappers in order to enrich API of wrapped type. Implicit conversion that converts String into WrappedString falls into that category.
Twitter's Effective Scala has a section about this issue.

Finding applicable implicit conversions in Scala

In the Coq proof assistant - which also has implicit conversions - it is possible to search for an implicit conversion using the SearchAbout T command, which returns all the things which have T in their type (which would include conversions to or from T).
Is there a way of finding all conversions to or from a type for Scala programmers? Note that the conversions might be defined outside the project that defines either the source or destination type.
To just quickly see if a conversion exists in the current scope between two reference types S and T, just type
((null:S):T)
and see if it compiles. With Eclipse Scala IDE >= 2.1M2 you can see which conversion is called, if implicit highlighting is enabled in the preferences.
Of course this requires you to guess both types (but you will probably already have a clear idea of what you want to convert to and from), and it requires the conversions to already be in scope.