Extractors as the only way to access things in reflection API

322 views
Skip to first unread message

Paul Butcher

unread,
Oct 11, 2012, 12:15:22 PM10/11/12
to scala-i...@googlegroups.com
This was briefly discussed here before:

https://groups.google.com/forum/#!msg/scala-internals/R1iZXfotqds/zqq8QjMJj74J

But I think that it's worth revisiting. I just answered the following question on SO:

http://stackoverflow.com/questions/12842729/finding-type-parameters-via-reflection-in-scala-2-10

Although the information is available, to my eyes at least, it's really ugly. And the fact that the question's been asked implies that it's not obvious. Adding an accessor would be really easy, wouldn't it? Why wouldn't we choose to do that?

--
paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park...
Who says I have a one track mind?

http://www.paulbutcher.com/
LinkedIn: http://www.linkedin.com/in/paulbutcher
MSN: pa...@paulbutcher.com
AIM: paulrabutcher
Skype: paulrabutcher

Paul Butcher

unread,
Oct 11, 2012, 12:23:54 PM10/11/12
to scala-i...@googlegroups.com

Paul Phillips

unread,
Oct 11, 2012, 1:23:02 PM10/11/12
to scala-i...@googlegroups.com
It's clear to me I'll have to write a lot of support functions; you may as well get used to it.

  def typeArgs(tp: Type) = tp match {
    case TypeRef(_, _, args) => args
    case _                   => Nil
  }

You can pimp it on if you want:

  implicit class TypeOps(val tp: Type) extends AnyVal {
    def typeArgs: List[Type] = tp match {
      case TypeRef(_, _, args) => args
      case _                   => Nil
    }
  }

At this stage of the game, doing this and organizing it nicely for inclusion in some future release will be more productive than lobbying for new methods.

Josh Suereth

unread,
Oct 11, 2012, 1:28:31 PM10/11/12
to scala-i...@googlegroups.com
The library is experimental in 2.10.1 for just this reason:  We weren't sure what to expose or not.

I think we need to set up a location to collect useful methods like this and slot them analysis/addition to the API.   We don't want every method under the sun, but there's a few methods (like this one) which are very useful and should be added before labelling the API "complete".

Any ideas on where we can accumulate such methods, or should we just poll stack overflow when figuring out what to add for 2.10.1?

- Josh

Paul Butcher

unread,
Oct 11, 2012, 4:12:34 PM10/11/12
to scala-i...@googlegroups.com
On 11 Oct 2012, at 18:28, Josh Suereth <joshua....@gmail.com> wrote:

Any ideas on where we can accumulate such methods, or should we just poll stack overflow when figuring out what to add for 2.10.1?

There may well be a few methods where we'll need to go through a discovery process to find what they are (I'll be suggesting a few based on my experience with ScalaMock), but I'm not sure that this is an example of one of them.

Rather, I'd suggest that wherever we have something that can be found through an extractor (e.g. any class within scala/reflect/api/Types.scala called <something>Extractor), we should also have an accessor.

This is the kind of thing that would fall out in the wash if the classes in the reflection API were case classes and it's a reasonable expectation on the part of a user of the API that they should behave that way, even if they're not implemented that way...

Eugene Burmako

unread,
Oct 11, 2012, 4:14:41 PM10/11/12
to scala-i...@googlegroups.com
We already do have accessors for every extractee. The thing is that they are declared in subclasses.

Paul Butcher

unread,
Oct 11, 2012, 4:18:34 PM10/11/12
to scala-i...@googlegroups.com
On 11 Oct 2012, at 21:14, Eugene Burmako <eugene....@epfl.ch> wrote:

We already do have accessors for every extractee. The thing is that they are declared in subclasses.

We do? Forgive me, as I've spent a long time looking for this accessor (for the type arguments to a TypeRef) and have failed to find it. Where should I be looking?

Eugene Burmako

unread,
Oct 11, 2012, 4:19:46 PM10/11/12
to scala-i...@googlegroups.com

Paul Butcher

unread,
Oct 11, 2012, 4:23:21 PM10/11/12
to scala-i...@googlegroups.com
On 11 Oct 2012, at 21:19, Eugene Burmako <eugene....@epfl.ch> wrote:

https://github.com/scalamacros/kepler/blob/47f6d964a013db0861c6effd8c8ea7c7a78bd11d/src/reflect/scala/reflect/api/Types.scala#L492

Ah - thanks.

So, given a Type, how do I get an instance of this. The following works:

res0.asInstanceOf[TypeRefApi].args

is that the right way? Or is there something analogous to ".asTerm" et al for symbols?

Eugene Burmako

unread,
Oct 11, 2012, 4:32:19 PM10/11/12
to scala-i...@googlegroups.com
You can even write .asInstanceOf[Type] without an unchecked warning, I think.

No, there are no similar casts. Somehow we never thought of that.

Paul Butcher

unread,
Oct 11, 2012, 4:46:44 PM10/11/12
to scala-i...@googlegroups.com
On 11 Oct 2012, at 21:32, Eugene Burmako <eugene....@epfl.ch> wrote:

No, there are no similar casts. Somehow we never thought of that.

OK - I would suggest that they're definitely worth adding - from a discoverability POV if nothing else. The fact that the OP on SO failed to find this, as did I after quite a lot of hunting, suggests that it's lacking discoverability :-)
Reply all
Reply to author
Forward
0 new messages