1) We want to make ClassTag a superclass of TypeTag because we want
the following to work:
def foo[T: TypeTag] = bar[T]
def bar[T: ClassTag] = ...
In other words, intuitively a TypeTag (aka Manifest) provides "more
info" than a ClassTag (aka ClassManifest), so we should be able to
pass a TypeTag when a ClassTag is required,.
Also it seems if we hold a full type in hand, we should at least be
able to generate an erased Java class from it, no?
2) However, it is actually not trivial to generate Java class from a
type. Reflection can do, but reflection is not always available.
So that led me to the following design:
class ClassTag[T](val erasure: jClass[_])
class TypeTag[T](val tpe: Type, erasure: jClass[_]) extends ClassTag(erasure)
It turns out that if we want to generate a class from a type in the
next stage, that's actually simple: emit an ldc instruction (see
TreeGen.mkClassOf).
3) However, in method transformTypeTagEvidenceParams, called during
macro expansion, we need to build TypeTags from just types. It seems
there is no way to get the erasure parameter in that case! In fact,
erasure could be a class we are about to define in the current run, so
evidently we cannot get a class symbol for it during macro expansion.
So it seems that the whole architecture falls like a house of cards,
and there is in fact no way to put ClassTags and TypeTags in an
inheritance relationship. Or am I wrong, and there is a way to produce
classes from types on the fly?
Cheers
-- Martin
It sounds more like you mean a custom classloader than reflection, is
that right? I'm not sure how reflection would help even if it were
available. I'm not sure how anything will which doesn't involve a
custom classloader, if you need to have macro expansion supply a class
object for a type which has no on-disk representation.
> So it seems that the whole architecture falls like a house of cards,
> and there is in fact no way to put ClassTags and TypeTags in an
> inheritance relationship. Or am I wrong, and there is a way to produce
> classes from types on the fly?
Perhaps you could you rebuild said house with poor man's inheritance?
object ClassTag {
implicit def fromTypeTag[T](tt: TypeTag[T]) = ClassTag[T](tt.erasure)
}
-jason
Yes, that's what it looks like. Do you see anything that would break
because of it?
-- Martin
Cheers
-- Martin
Essentially, it's the code in ScalaToJava, which forms part of Scala
reflection, and uses Java reflection. For instance it uses
Class.forName, or Array.newInstance.
Cheers
-- Martin
Cheers
-- Martin
> On 16 March 2012 18:54, martin odersky <martin....@epfl.ch> wrote:
>>
>> On Fri, Mar 16, 2012 at 6:38 PM, Eugene Burmako <eugene....@epfl.ch>
>> wrote:
>> >>class ClassTag[T](val erasure: jClass[_])
>> > Correct me if I wrong, but does this mean that we cannot generate a
>> > ClassTag for a type that is defined in the current compilation run?
>>
>> Yes, that's what it looks like. Do you see anything that would break
>> because of it?
>>
>> -- Martin
>
>
--
Martin Odersky
Prof., EPFL and Chairman, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967