Type-class/implicit discoverability in Scala - scala

In Scala, is there a way to "discover" all the type classes in scope; or more generally, all the implicits in scope? In ghci, :info Monad shows all the available Monads, and :info Maybe shows all the available type classes for Maybe, I wonder if something similar exists in the Scala.

No, Scala does not have something like that. There are a few compiler options as "-Xlog-implicits" that print a bit more information, if implicits are not applicable. But there is nothing to list all implicits available in a certain context.
One could try to do this via macros, but even the macro api does not provide a direct way to do that. There is access to the typer via the compiler API and implicit search. But this API is very complicated.

Related

In Scala, is the reflection module ill suited for dealing with runtime, possibly erased types?

Considering a simple use case to extract fields of an object in Java reflection:
val fields = this.getClass.getDeclaredFields
it may return incomplete information if generic type is used, but it is short, fast and can handle most cases.
In Scala reflection module (scala.reflect), it appears that such one-liner doesn't exist, the shortest code I know of that can successfully handle this case is:
trait Thing[T <: Thing[T]{
implicit ev: TypeTag[T]
scala.reflect.runtime.universe.typeOf[T].members
}
This uses a redundant F-bounded polymorphism and a TypeTag doesn't carry extra information comparing to a Java class, is there any way to make it shorter, at least as short as Java (which is a very verbose language)?
Thanks a lot for your advice
I'm not sure that in this specific case
this.getClass.getDeclaredFields
is much shorter than
def fields[T: TypeTag](t: T) = typeOf[T].decls
fields(this)
Anyway you can still use Java reflection in Scala.
Sometimes Scala reflection is more verbose than Java reflection but Scala reflection allows to do things (in Scala terms) that can't be done with Java reflection (for example if corresponding Scala concepts are absent in Java).
It's not true that
TypeTag doesn't carry extra information comparing to a Java class
Types and classes are different concepts. Maybe you meant ClassTags.
To use or not to use F-bounded polymorphism is your choice.

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.

Scala Case Class Map Expansion

In groovy one can do:
class Foo {
Integer a,b
}
Map map = [a:1,b:2]
def foo = new Foo(map) // map expanded, object created
I understand that Scala is not in any sense of the word, Groovy, but am wondering if map expansion in this context is supported
Simplistically, I tried and failed with:
case class Foo(a:Int, b:Int)
val map = Map("a"-> 1, "b"-> 2)
Foo(map: _*) // no dice, always applied to first property
A related thread that shows possible solutions to the problem.
Now, from what I've been able to dig up, as of Scala 2.9.1 at least, reflection in regard to case classes is basically a no-op. The net effect then appears to be that one is forced into some form of manual object creation, which, given the power of Scala, is somewhat ironic.
I should mention that the use case involves the servlet request parameters map. Specifically, using Lift, Play, Spray, Scalatra, etc., I would like to take the sanitized params map (filtered via routing layer) and bind it to a target case class instance without needing to manually create the object, nor specify its types. This would require "reliable" reflection and implicits like "str2Date" to handle type conversion errors.
Perhaps in 2.10 with the new reflection library, implementing the above will be cake. Only 2 months into Scala, so just scratching the surface; I do not see any straightforward way to pull this off right now (for seasoned Scala developers, maybe doable)
Well, the good news is that Scala's Product interface, implemented by all case classes, actually doesn't make this very hard to do. I'm the author of a Scala serialization library called Salat that supplies some utilities for using pickled Scala signatures to get typed field information
https://github.com/novus/salat - check out some of the utilities in the salat-util package.
Actually, I think this is something that Salat should do - what a good idea.
Re: D.C. Sobral's point about the impossibility of verifying params at compile time - point taken, but in practice this should work at runtime just like deserializing anything else with no guarantees about structure, like JSON or a Mongo DBObject. Also, Salat has utilities to leverage default args where supplied.
This is not possible, because it is impossible to verify at compile time that all parameters were passed in that map.

Anything in Scala equivalent to C#'s `dynamic`?

I believe the answer is no, but wouldn't hurt to check: anything in Scala that's equivalent to C#'s dynamic keyword? Anything on the horizon?
I know about scala.Dynamic, which is not the same thing - in C# you don't know the types at compile time, and the dynamic type propagates.
I also know about invokedynamic, which is not the same thing - invokedynamic is the infrastructure that would make language constructs like dynamic performant.
Anything on the horizon?
Yes there is: objects extending the Dynamic trait behave similarly to variables declared as dynamic in C#.
This is a new feature in Scala 2.9 (but still considered experimental), see the scaladoc at http://www.scala-lang.org/api/current/index.html#scala.Dynamic.

Does Scala have introspection capable of something similar to Python's dir()?

Yes, I know it's considered lazy by the non-Pythonistas. The reason I ask is that documentation is still woefully lacking in many Scala libraries (e.g. Scala-dbc, but that's not all I'm looking at), and if I could see the attributes of an object/class at runtime, I could at least figure out what's available. Thanks.
Scala does not have a reflection API. The only way to access this information is to use the Java reflection API. This has the disadvantage that the structure may change as the way Scala is represented in Java classes and interfaces may change in the future.
scala> classOf[AnyRef].getMethods
res0: Array[java.lang.reflect.Method] = Array(public final void ...
Some specific type information that is present in the byte code can be accessed with the ScalaSigParser.
import tools.scalap.scalax.rules.scalasig._
import scala.runtime._
val scalaSig = ScalaSigParser.parse(classOf[RichDouble])
That's one of my main uses for REPL. Type the object's name, dot, and then TAB and it will show all available methods.
It isn't perfect. For one thing, it shows protected methods, which won't be available unless you are extending the class. For another thing, it doesn't show methods available through implicit conversion.
And, of course, the IDEs are all capable of doing that.
You might want something like the following which would give you what you need. In this case, it operates on a String, obviously.
val testStr = "Panda"
testStr.getClass.getMethods.foreach(println)
Does that work?
You may want to use this little helper to beef up the REPL