In my Ammonite REPL, I have a pair of functions which are very useful for poking at things and seeing what they are:
/**
* Get the `Type` object of [[T]]
*/
def typeOf[T: WeakTypeTag]: Type
/**
* Get the `Type` object representing the type of `t`
*/
def typeOf[T: WeakTypeTag](t: => T): Type
This works surprisingly well! I can throw at it types, values, objects, primitives, etc. and get useful reflective knowledge about what those things can do.
However, it fails in certain cases, because not everything in Scala is a value!
@ typeOf(scala)
Compilation Failed
Main.scala:15: package scala is not a value
val res11 = (typeOf(scala))
^
@ typeOf("".substring)
Compilation Failed
Main.scala:15: ambiguous reference to overloaded definition,
both method substring in class String of type (x$1: Int, x$2: Int)String
and method substring in class String of type (x$1: Int)String
match expected type ?
val res11 = (typeOf("".substring))
^
Ideally, I'd like people to be able to reflect on packages and methods just as they can reflect on types and objects. A package's type has useful information on what classes and sub-packages it contains, and a methods type is extremely useful in telling you what parameters that method takes, what it returns and what overloads it has
Now, clearly I can't do this in normal Scala, but is there any easy way I can hack the compiler to make this work? Or any easy workarounds that people can think of? I am very much trying to avoid all the magic-syntax-command the old Scala REPL has, and I could do so neatly, if not for this irregularity in the language for things that aren't values.