SIP 17: Can the Dynamic trait be more dynamic?

259 views
Skip to first unread message

Chris Hodapp

unread,
Mar 28, 2012, 12:59:27 AM3/28/12
to scala...@googlegroups.com
After reading the SIP 17 proposal, I began to think about whether, rather than being a marker trait, Dynamic could provide concrete implementations of applyDynamic, applyDynamicNamed, selectDynamic, and updateDynamic that used reflection to call through to normally-defined methods if they exist. I thought that this would make "Dynamic" way more useful, since methods could accept parameters of type "Dynamic" and use them properly. After some experimenting, I realized that this does seem to be possible. See this for the result of my experimentation. If you paste this into the REPL, you should be able to define f: Foo and then call f.applyDynamic("bar", 4).as[Int].

Note that:
  • It is extremely rough and doesn't handle a bunch of key cases. This is just a proof that something like this could work (I was in a hurry to share).
  • I also changed the signature of applyDynamic so that it's return type is "Dynamic". This allows you to stay in "Dynamic-land" for extended periods without too much pain. I created a system for boxing non-Dynamic values.
  • It will be necessary to provide implementations of this method (and of the Dynamic box class) for each parameter list length that we want to support.
  • You do prevent the type checker from detecting some errors this way, since you can now call any method name with any arguments on a Dynamic object. The safety that existed before was something of an illusion, though, since you could easily use a method name not expected by the applyDynamic author with parameter types they did expect and pass type checking.
  • Crazy thought: rather than having users override this method, it could act more like Ruby's method_missing and call some user-defined method only if it can't call a normal method.
Thoughts?

Chris Hodapp

unread,
Mar 28, 2012, 1:23:30 AM3/28/12
to scala...@googlegroups.com
I've just realized that 1) this is actually what is being referred to as "DynamicRef" in another thread and 2) @specialized annotations are not at all practical for long parameter lists.

I am still curious about what people think about having the *Dynamic return Dynamic instances, though.

Eugene Burmako

unread,
Mar 28, 2012, 2:58:30 AM3/28/12
to <scala-sips@googlegroups.com>
1) How would you support auto-injecting implicit conversions where necessary? 
2) Same question for implicit parameters.
3) What about multiple parameter lists?


Chris Hodapp

unread,
Mar 28, 2012, 3:30:00 AM3/28/12
to scala...@googlegroups.com
I can't think of any way to do auto-injecting of implicit conversions without language support and I'm not even sure how that would work.

Implicit parameters just look like regular parameters through Java reflection. Hopefully Scala reflection will fix this. Even if does, we will still have the same problem as we do with conversions.
 
Multiple parameter lists look like one long parameter list through Java reflection. Hopefully Scala reflection will fix this too. If it does, it may be possible to handle those properly.

Maybe there is a solution to the implicits problem that I'm not thinking of...

Chris Hodapp

unread,
Mar 28, 2012, 3:44:04 AM3/28/12
to scala...@googlegroups.com
More specifically, you would first need some way to represent  a bundle of implicits. You would be able to query this bundle for implicits matching some signature. Finally, you would need to be able to get one of these bundles from the calling scope (i.e. implicits that were in scope when this method was called), another from the class of the class of the object, and finally one from the class of each parameter and argument type (!). If Scala reflection were to support this sort of black magic, maybe something could be made to work...  

Eugene Burmako

unread,
Mar 28, 2012, 3:46:28 AM3/28/12
to scala...@googlegroups.com, Martin Odersky
Speaking of implicits, I honestly have no idea.

@Martin: Is there a theoretical chance we can have this working? Say, if we pickle all symbols (including local ones) and serialize current scope, we might be able to typecheck against it during a subsequent reflective compilation. That'd be helpful not only for DynamicRef, but also for reification itself (no need to reify symbols, just reify naked trees and then typecheck them in serialized context), and hygiene (reify macro definition context, and you have hygiene even for handcrafted ASTs). Not saying we should do it in 2.10, of course.

On a second thought, multiple parameter lists can work. My main problem was with distinguishing between when you're still in partial apply state (e.g. when you've applied 2 argument lists of 3) and when you're already done with the application. But since we always return Dynamic and use as[T] to case it back to static types, we're fine.

Eugene Burmako

unread,
Mar 28, 2012, 3:51:51 AM3/28/12
to scala...@googlegroups.com
By the way, speaking of the original idea, I think it's great, but personally I have my hands full with macros.

Though if you're interested in turning your prototype into something solid, I can provide some assistance (starting from how to build Scala trunk and how to use the new Scala reflection API).

David Hall

unread,
Mar 28, 2012, 2:01:15 AM3/28/12
to scala...@googlegroups.com
On Tue, Mar 27, 2012 at 10:23 PM, Chris Hodapp <clho...@gmail.com> wrote:
> I've just realized that 1) this is actually what is being referred to as
> "DynamicRef" in another thread and 2) @specialized annotations are not at
> all practical for long parameter lists.
>
> I am still curious about what people think about having the *Dynamic return
> Dynamic instances, though.

The whole point of the current version of Dynamic is to let you
implement it however you want: scalac just does method desugaring in
this way if you inherit from this trait. That's it, and that's why
it's so beautiful.

So you can define JRubyDynamic that always returns JRubyDynamic, or
JythonDynamic that always returns JythonDynamic, or you can return an
alternation of the two, if that's what suits you. Each use case will
be a little different.

The proposal is by far more flexible...

-- David

Erik Osheim

unread,
Mar 28, 2012, 1:28:23 AM3/28/12
to scala...@googlegroups.com
On Tue, Mar 27, 2012 at 10:23:30PM -0700, Chris Hodapp wrote:
> I've just realized that 1) this is actually what is being referred to as
> "DynamicRef" in another thread and 2) @specialized annotations are not at
> all practical for long parameter lists.

When writing a lot of specialized code, I often alias the annotation to
something shorter, e.g.:

import scala.{specialized => spec}
def foo[@spec T](t:T) = ...

(I think I picked this trick up from Marc Millstone.)

-- Erik

Chris Hodapp

unread,
Mar 28, 2012, 11:26:46 AM3/28/12
to scala...@googlegroups.com
I wasn't referring to the length of the method signature, but rather the number of generated methods. For each @specialized-annotated type, you multiply the number of generated methods by ten (the number of AnyVal types plus one for AnyVal). So a method with two @specialized parameters actually becomes 100 methods.

Chris Hodapp

unread,
Mar 28, 2012, 11:40:45 AM3/28/12
to scala...@googlegroups.com
I lied. It does something more complicated. The point remains, though: the number of generated methods grows too fast.

Erik Osheim

unread,
Mar 28, 2012, 11:45:14 AM3/28/12
to scala...@googlegroups.com
On Wed, Mar 28, 2012 at 08:26:46AM -0700, Chris Hodapp wrote:
> I wasn't referring to the length of the method signature, but rather the
> number of generated methods. For each @specialized-annotated type, you
> multiply the number of generated methods by ten (the number of AnyVal types
> plus one for AnyVal). So a method with two @specialized parameters actually
> becomes 100 methods.

You can limit this to the specialized versions you want, e.g.:

def bar[@spec(Int) T, @spec(Int, Double) U](t:T, u:U) = (t, u)

This will only create 3 methods (1 normal one plus 1 x 2 specialized
versions):

bar
bar$mIDc$sp
bar$mIIc$sp

You actually have a lot of control over how many (or few) extra
methods/classes you want.

-- Erik

Chris Hodapp

unread,
Mar 28, 2012, 12:33:17 PM3/28/12
to scala...@googlegroups.com
That makes a lot of sense. Given that this is a goal for the Dyamic trait, what I'm proposing should be defined in a subtrait of the Dynamic trait (e.g. as ScalaDynamic or DynamicRef).

Chris Hodapp

unread,
Mar 28, 2012, 12:38:39 PM3/28/12
to scala...@googlegroups.com
That sounds great. It is possible that nothing useful would come of it, given the problems with implicits, but I would like to try. As has been pointed out, this should be implemented as a subtrait of the base Dyamic trait (which can have the behavior specified in SIP 17), so there should be plenty of time to get this right if it is possible.

Alex Boisvert

unread,
Mar 28, 2012, 1:09:46 PM3/28/12
to scala...@googlegroups.com
On Wed, Mar 28, 2012 at 12:30 AM, Chris Hodapp <clho...@gmail.com> wrote:
I can't think of any way to do auto-injecting of implicit conversions without language support and I'm not even sure how that would work.

I'm unsure if I understand what you want but you could use a marker trait + implicit conversion as an indirection,

trait DynamicWithImplicit[T]

// capture implicit at the call site
implicit def capture[T](dynamic: DynamicWithImplicits[T])(implicit i: T): Dynamic = {
  new DynamicImpl(dynamic)(i)
}

alex

Eugene Burmako

unread,
Mar 28, 2012, 1:13:18 PM3/28/12
to scala...@googlegroups.com
When dispatching an invocation of a dynamic method I want to be able to conjure implicit conversions / implicit parameters for arbitrary types. 

Something like implicitly[T], but for T that I can provide at runtime.

Chris Hodapp

unread,
Mar 28, 2012, 3:44:31 PM3/28/12
to scala...@googlegroups.com
We definitely need that, but we also need closures of the implicit conversions that were in scope when a class was defined. That is the part that I'm more unsure about...

Eugene Burmako

unread,
Mar 28, 2012, 4:39:52 PM3/28/12
to scala...@googlegroups.com
Hmm why would you want implicits from class definition scope? I think it makes more sense to resolve implicits using callsite scope.

Chris Hodapp

unread,
Mar 28, 2012, 5:08:15 PM3/28/12
to scala...@googlegroups.com
I think you need to search both. I believe that this is an example of code that would only work if it searches the class definition scope (and it does compile and run)

Eugene Burmako

unread,
Mar 28, 2012, 5:29:20 PM3/28/12
to scala...@googlegroups.com
Ah, I see what you mean. I thought that you wanted to use implicits from the scope of DynamicRep or its inheritor, my bad.

To my mind, this part is actually simple, since that's what compiler does reliably across multiple compilation runs, so theoretically we can do the same. There is a mechanism in place, called pickling, that saves all symbols reachable from top-level definitions in ScalaSignature annotations. This is, actually, how Scala reflection will work in 2.10 - unpickle the stuff from ScalaSignatures and expose it to the programmer.

What I'm worried about is that local symbols (local variables, classes, defs) don't get pickled at all. Therefore most information about what was happening at the callsite is irreversibly lost. And even despite the fact that we theoretically can save all implicit vals and defs from the callsite scope, there are some implicits that get summoned out of thin air (e.g. typetags aka manifests).

So we do need to have a way to reify scopes, or we could live with DynamicRef not working with implicits. Which is also not that bad - this is what they have to do in .NET.

Eugene Burmako

unread,
Mar 28, 2012, 5:34:34 PM3/28/12
to scala...@googlegroups.com
Also, there's an unrelated point we need to think of w.r.t DynamicRef.

Reflective compiler aka ToolBox supports type inference, so it'll be possible to define a generic method and invoke it with DynamicRef having its type arguments inferred.

What is not possible is providing explicit type arguments. For example, I'd like to be able to write:

val list = List.asDynamic
list[Int]()

However, this won't work, because applyDynamic in DynamicRef doesn't have type parameters. Hmm, on a second thought using the OverloadHack trick we could provide overloads with different number of type parameters. But then we would have to give up specialization. Any ideas?

Eugene Burmako

unread,
Mar 28, 2012, 5:41:11 PM3/28/12
to scala...@googlegroups.com
My suggestion here would be to add a new method "withTypeArguments" with the following rewrite ru

val foo = foo0.asDynamic
foo[T](bar)

gets translated to

foo.withTypeArguments(implicitly[TypeTag[T]]).applyDynamic(“bar”)()

Daniel Sobral

unread,
Mar 29, 2012, 2:57:44 PM3/29/12
to scala...@googlegroups.com
On Wed, Mar 28, 2012 at 13:38, Chris Hodapp <clho...@gmail.com> wrote:
> That sounds great. It is possible that nothing useful would come of it,
> given the problems with implicits, but I would like to try. As has been
> pointed out, this should be implemented as a subtrait of the base Dyamic
> trait (which can have the behavior specified in SIP 17), so there should be
> plenty of time to get this right if it is possible.

Actually, I think it is important to have solid use case
implementations right now, to avoid having to change (again) Dynamic
in the future.

--
Daniel C. Sobral

I travel to the future all the time.

Chris Hodapp

unread,
Mar 30, 2012, 2:05:03 PM3/30/12
to scala...@googlegroups.com
Hey, I'm working on building a more solid version. I've managed to check out the Scala source from Github and build it, but I could really use a good discussion on what capabilities the new reflection API gives or at least how I should approach learning it.

Daniel Sobral

unread,
Mar 30, 2012, 3:51:12 PM3/30/12
to scala...@googlegroups.com
On Fri, Mar 30, 2012 at 15:05, Chris Hodapp <clho...@gmail.com> wrote:
> Hey, I'm working on building a more solid version. I've managed to check out
> the Scala source from Github and build it, but I could really use a good
> discussion on what capabilities the new reflection API gives or at least how
> I should approach learning it.

I'm all for that, particularly because I know nothing about it.

--

Eugene Burmako

unread,
Mar 31, 2012, 4:09:31 AM3/31/12
to scala...@googlegroups.com
The heart of the reflection API is declared here: https://github.com/scala/scala/blob/master/src/library/scala/reflect/api/. This is not an extensive list of the stuff that we want to expose (e.g. in the near future I will publish Positions), neither it's a final API (e.g. we're planning to rehash Symbols), but that's what we have now. For a peek into features that might end up in trunk, you can also check https://github.com/scalamacros/kepler/branches, but you'll be safer not using them now.

Unlike in reflection libraries for popular VM languages, reflection in Scala doesn't start with foo.getClass()/foo.GetType(), but is encapsulated in a separate entity called mirror. There can be lots of mirrors (e.g. compiler itself is a mirror, and I've written a custom mirror for macros), but the default mirror is scala.reflect.mirror. If you fancy, you can write "import scala.reflect.mirror._" and use its functionality unqualified.

Almost everything in the reflection API is path-dependent. We say that trees, types and whatnot are bound to their corresponding universe.

Speaking of universes, here we go: https://github.com/scala/scala/blob/master/src/library/scala/reflect/api/Universe.scala. Universe is a mash-up composed of essential functionality, which is abstracted from its runtime. Why abstract from the  runtime? Because it's different across different mirrors. E.g. compiler mirror uses its own classloading subsystem to read, parse and load classfiles, reflection mirror uses classpaths and Class.forName, and macro mirror uses special classpaths.

So what new functionality does Mirror bring to Universe? Take a look here: https://github.com/scala/scala/blob/master/src/library/scala/reflect/api/Mirror.scala. Here we see such things as loading symbols by name (analogue of Class.forName), conversions from Java to Scala reflection concepts and vice versa, along with facilities to reflectively work with fields and methods.

Okay, I mentioned symbols. What are they? Let's take a look: https://github.com/scala/scala/blob/master/src/library/scala/reflect/api/Symbols.scala. Everything that is declared in a Scala program (or in a referenced Java program) ends up as a symbol. Declared a top-level class? Symbol. Declared an inner class? Symbol. Declared a method? Symbol. Declared a field? You get the drill. After compiler assigns symbols to the declarations, it then uses these symbols during typechecking to link declarations to their usages. For example, when you write "new C", the compiler looks up a symbol for this C, and assigns it to the Apply node that represents this invocation. This is not directly relevant to what you're going to do, but hopefully it explains why we need symbols in general.

To recap this stream of consciousness. To reflect against a Scala class for some object you need to:
1) Get a Java class of this object
4) Use one of the "declaration" methods that expose symbols declared by that type: https://github.com/scala/scala/blob/master/src/library/scala/reflect/api/Types.scala#L14
5) Do some stuff with the symbols you've loaded, e.g. invoke a corresponding method: https://github.com/scala/scala/blob/master/src/library/scala/reflect/api/Mirror.scala#L58.

Eugene Burmako

unread,
Mar 31, 2012, 4:11:29 AM3/31/12
to scala-sips, Christopher Vogt
Also, I've heard that Christopher (/cc'd) is also experimenting with
DynamicRef. I think, you guys could discuss and share your ideas.

On Mar 30, 8:05 pm, Chris Hodapp <clhoda...@gmail.com> wrote:
> Hey, I'm working on building a more solid version. I've managed to check
> out the Scala source from Github and build it, but I could really use a
> good discussion on what capabilities the new reflection API gives or at
> least how I should approach learning it.
>
>
>
> On Wednesday, March 28, 2012 11:38:39 AM UTC-5, Chris Hodapp wrote:
>
> > That sounds great. It is possible that nothing useful would come of it,
> > given the problems with implicits, but I would like to try. As has been
> > pointed out, this should be implemented as a subtrait of the base Dyamic
> > trait (which can have the behavior specified in SIP 17), so there should be
> > plenty of time to get this right if it is possible.
>
> > On Wednesday, March 28, 2012 2:51:51 AM UTC-5, Eugene Burmako wrote:
>
> >> By the way, speaking of the original idea, I think it's great, but
> >> personally I have my hands full with macros.
>
> >> Though if you're interested in turning your prototype into something
> >> solid, I can provide some assistance (starting from how to build Scala
> >> trunk and how to use the new Scala reflection API).
>
> >> On 28 March 2012 09:44, Chris Hodapp <clhoda...@gmail.com> wrote:
>
> >>> More specifically, you would first need some way to represent  a bundle
> >>> of implicits. You would be able to query this bundle for implicits matching
> >>> some signature. Finally, you would need to be able to get one of these
> >>> bundles from the calling scope (i.e. implicits that were in scope when this
> >>> method was called), another from the class of the class of the object, and
> >>> finally one from the class of each parameter and argument type (!). If
> >>> Scala reflection were to support this sort of black magic, maybe something
> >>> could be made to work...
>
> >>> On Wednesday, March 28, 2012 2:30:00 AM UTC-5, Chris Hodapp wrote:
>
> >>>> I can't think of any way to do auto-injecting of implicit conversions
> >>>> without language support and I'm not even sure how *that* would work.
>
> >>>> Implicit parameters just look like regular parameters through Java
> >>>> reflection. Hopefully Scala reflection will fix this. Even if does, we will
> >>>> still have the same problem as we do with conversions.
>
> >>>> Multiple parameter lists look like one long parameter list through Java
> >>>> reflection. Hopefully Scala reflection will fix this too. If it does, it
> >>>> may be possible to handle those properly.
>
> >>>> Maybe there is a solution to the implicits problem that I'm not
> >>>> thinking of...
>
> >>>> On Wednesday, March 28, 2012 1:58:30 AM UTC-5, Eugene Burmako wrote:
>
> >>>>> 1) How would you support auto-injecting implicit conversions where
> >>>>> necessary?
> >>>>> 2) Same question for implicit parameters.
> >>>>> 3) What about multiple parameter lists?
>
> >>>>> On 28 Mar 2012, at 06:59, Chris Hodapp wrote:
>
> >>>>> After reading the SIP 17 proposal, I began to think about whether,
> >>>>> rather than being a marker trait, Dynamic could provide concrete
> >>>>> implementations of applyDynamic, applyDynamicNamed, selectDynamic, and
> >>>>> updateDynamic that used reflection to call through to normally-defined
> >>>>> methods if they exist. I thought that this would make "Dynamic" way more
> >>>>> useful, since methods could accept parameters of type "Dynamic" and use
> >>>>> them properly. After some experimenting, I realized that this does seem to
> >>>>> be possible. See this <https://gist.github.com/2223633> for the
> >>>>> result of my experimentation. If you paste this into the REPL, you should
> >>>>> be able to define f: Foo and then call f.applyDynamic("bar", 4).as[Int].
>
> >>>>> Note that:
>
> >>>>>    - It is extremely rough and doesn't handle a bunch of key cases.
> >>>>>    This is just a proof that something like this could work (I was in a hurry
> >>>>>    to share).
> >>>>>    - I also changed the signature of applyDynamic so that it's return
> >>>>>    type is "Dynamic". This allows you to stay in "Dynamic-land" for extended
> >>>>>    periods without too much pain. I created a system for boxing non-Dynamic
> >>>>>    values.
> >>>>>    - It will be necessary to provide implementations of this method
> >>>>>    (and of the Dynamic box class) for each parameter list length that we want
> >>>>>    to support.
> >>>>>    - You do prevent the type checker from detecting some errors this
> >>>>>    way, since you can now call any method name with any arguments on a Dynamic
> >>>>>    object. The safety that existed before was something of an illusion,
> >>>>>    though, since you could easily use a method name not expected by the
> >>>>>    applyDynamic author with parameter types they did expect and pass type
> >>>>>    checking.
> >>>>>    - Crazy thought: rather than having users override this method, it
> >>>>>    could act more like Ruby's method_missing and call some user-defined method
> >>>>>    only if it can't call a normal method.
>
> >>>>> Thoughts?
>
> >>> On Wednesday, March 28, 2012 2:30:00 AM UTC-5, Chris Hodapp wrote:
>
> >>>> I can't think of any way to do auto-injecting of implicit conversions
> >>>> without language support and I'm not even sure how *that* would work.
>
> >>>> Implicit parameters just look like regular parameters through Java
> >>>> reflection. Hopefully Scala reflection will fix this. Even if does, we will
> >>>> still have the same problem as we do with conversions.
>
> >>>> Multiple parameter lists look like one long parameter list through Java
> >>>> reflection. Hopefully Scala reflection will fix this too. If it does, it
> >>>> may be possible to handle those properly.
>
> >>>> Maybe there is a solution to the implicits problem that I'm not
> >>>> thinking of...
>
> >>>> On Wednesday, March 28, 2012 1:58:30 AM UTC-5, Eugene Burmako wrote:
>
> >>>>> 1) How would you support auto-injecting implicit conversions where
> >>>>> necessary?
> >>>>> 2) Same question for implicit parameters.
> >>>>> 3) What about multiple parameter lists?
>
> >>>>> On 28 Mar 2012, at 06:59, Chris Hodapp wrote:
>
> >>>>> After reading the SIP 17 proposal, I began to think about whether,
> >>>>> rather than being a marker trait, Dynamic could provide concrete
> >>>>> implementations of applyDynamic, applyDynamicNamed, selectDynamic, and
> >>>>> updateDynamic that used reflection to call through to normally-defined
> >>>>> methods if they exist. I thought that this would make "Dynamic" way more
> >>>>> useful, since methods could accept parameters of type "Dynamic" and use
> >>>>> them properly. After some experimenting, I realized that this does seem to
> >>>>> be possible. See this <https://gist.github.com/2223633> for the
> >>>>> result of my experimentation. If you paste this into the REPL, you should
> >>>>> be able to define f: Foo and then call f.applyDynamic("bar", 4).as[Int].
>
> >>>>> Note that:
>
> >>>>>    - It is extremely rough and doesn't handle a bunch of key cases.
> >>>>>    This is just a proof that something like this could work (I was in a hurry
> >>>>>    to share).
> >>>>>    - I also changed the signature of applyDynamic so that it's return
> >>>>>    type is "Dynamic". This allows you to stay in "Dynamic-land" for extended
> >>>>>    periods without too much pain. I created a system for boxing non-Dynamic
> >>>>>    values.
> >>>>>    - It will be necessary to provide implementations of this method
> >>>>>    (and of the Dynamic box class) for each parameter list length that we want
> >>>>>    to support.
> >>>>>    - You do prevent the type checker from detecting some errors this
> >>>>>    way, since you can now call any method name with any arguments on a Dynamic
> >>>>>    object. The safety that existed before was something of an illusion,
> >>>>>    though, since you could easily use a method name not expected by the
> >>>>>    applyDynamic author with parameter types they did expect and pass type
> >>>>>    checking.
> >>>>>    - Crazy thought: rather than having users override this method, it

Christopher Vogt

unread,
Mar 31, 2012, 7:53:46 AM3/31/12
to scala...@googlegroups.com
In the Scala Team, we are currently thinking of offering two subs of Dynamic, probably called DynamicReflect and DynamicProxy. I started working on it and would be happy to cooperate with you.

They will look something like this:

trait DynamicReflect extends Dynamic{
  val target : Any = this // possibly default to this
  def applyDynamic( name: String )( args: Any* ) = invoke( target, name )( args:_* ) // invoke call looks different in reality
}

class DynamicProxy( val target : Any ) extends DynamicReflect

DynamicReflect implements Dynamic and has a certain member target, which it redirects calls to. DynamicProxy is a class which takes the target as an argument.

Personally I am not certain of its use cases, but there seems to be demand. Maybe you can elaborate on the use cases. In any case it's a fun experiment and a good test case for Dynamic and reflection.

Chris

Christopher Vogt

unread,
Mar 31, 2012, 8:04:11 AM3/31/12
to scala...@googlegroups.com

Reflective compiler aka ToolBox supports type inference, so it'll be possible to define a generic method and invoke it with DynamicRef having its type arguments inferred.

I was thinking of that, too. The runtime (aka reflective) compiler seems like the sensible way to use compiler features like implicits reliably at runtime. It would also help with selecting the right method in case of overloading.

using the OverloadHack trick we could provide overloads with different number of type parameters. But then we would have to give up specialization.

Could you elaborate on the problem? 

Eugene Burmako

unread,
Mar 31, 2012, 8:13:37 AM3/31/12
to scala...@googlegroups.com
You won't be able to infer implicits using toolboxes, because you no longer have the original lexical scope when compiling stuff reflectively. If only we could reify scopes :)

Well, normally you cannot overload only by the number of tparams, because of erasure. But you can use these guys to hack around: https://github.com/TiarkRompf/virtualization-lms-core/blob/master/src/util/OverloadHack.scala.

Christopher Vogt

unread,
Mar 31, 2012, 9:34:16 AM3/31/12
to scala...@googlegroups.com

You won't be able to infer implicits using toolboxes, because you no longer have the original lexical scope when compiling stuff reflectively. If only we could reify scopes :)

I see :). Let's discuss it in one of our meetings.

martin odersky

unread,
Mar 31, 2012, 9:42:16 AM3/31/12
to scala...@googlegroups.com


On Sat, Mar 31, 2012 at 3:34 PM, Christopher Vogt <jan.christ...@gmail.com> wrote:

You won't be able to infer implicits using toolboxes, because you no longer have the original lexical scope when compiling stuff reflectively. If only we could reify scopes :)

I see :). Let's discuss it in one of our meetings.

Reify scopes: That looks really hard and inefficient. And, it's not stable under splicing. So I believe this is a no-go.

 - Martin

--
Martin Odersky
Prof., EPFL and Chairman, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967

Christopher Vogt

unread,
Mar 31, 2012, 9:54:16 AM3/31/12
to scala...@googlegroups.com
Documentation on Scala Reflection is sparse at the moment. For now it is best you get started with a little example and browse the code/APIs looking for the stuff you need. For our use case I put together two alternative starting points, one using the reflective compiler, one using scala reflection.

https://github.com/cvogt/scala/blob/e86faecbe4283377b313c9bfb8621970a6735e12/src/library/scala/reflect/DynamicReflect.scala

The scala reflection based one works for non-overloaded methods. @Eugene/@Martin Can you please check why the reflective compiler example fails?

/Chris

Eugene Burmako

unread,
Mar 31, 2012, 10:10:31 AM3/31/12
to scala...@googlegroups.com
I think, toolbox fails because you use an unqualified name. Also, Literal(Constant(x)) won't work unless x is a literal (i.e. number, string, boolean or a Class[_]). You need to use free vars to pass values between metalevels. By the end of this weekend, I'll merge reify v2 into develop, and we can discuss how this can be done.

Reflection fails because member returns OverloadedSymbol, so you have to perform overload resolution by yourself. Maybe you can leverage the typeCheck method in the toolbox.

Christopher Vogt

unread,
Apr 13, 2012, 7:39:22 PM4/13/12
to scala...@googlegroups.com
I created a pull request to scala master with a more evolved dynamic proxy https://github.com/scala/scala/pull/393 . It handles stuff like named arguments, default arguments, setters, unboxed primitive types, ...
Reply all
Reply to author
Forward
0 new messages