See also the discussion page.
This proposal is to amend the spec with a normative set of meta-objects which must be present in any program and accessible at runtime. The meta-objects may be immutable, and they may be constructed lazily, but in all other respects they should appear to the programmer as “normal” objects.
There is a function:
intrinsic function typeOf(e: *): intrinsic::Type;
Which, for any expression e, returns a type meta-object which is a runtime description of the type of e. Type meta-objects have the following signature:
use default namespace intrinsic;
interface Type
{
function canConvertTo(t: Type): Boolean;
function isSubtypeOf(t: Type): Boolean;
}
interface Field
{
function namespace() : String;
function name(): String;
function type(): Type;
}
type FieldIterator = iterator::IteratorType.<Field>;
interface NominalType extends Type
{
function name(): String;
function namespace(): String;
function superTypes(): IteratorType.<ClassType>;
function publicMembers(): FieldIterator;
function publicStaticMembers(): FieldIterator;
}
interface InterfaceType extends NominalType
{
function implementedBy():IteratorType.<ClassType>
}
type TypeIterator = iterator::IteratorType.<Type>;
type ValueIterator = iterator::IteratorType.<*>;
interface ClassType extends NominalType
{
function construct(typeArgs: TypeIterator, valArgs: ValueIterator): Object;
}
interface UnionType extends Type
{
function members(): TypeIterator;
function construct(typeArgs: TypeIterator, valArgs: ValueIterator): *;
}
interface FieldValue
{
function namespace() : String;
function name(): String;
function value(): *;
}
type FieldValueIterator = iterator::IteratorType.<FieldValue>;
interface RecordType extends Type
{
function fields(): FieldIterator;
function construct(typeArgs: TypeIterator, valArgs: FieldValueIterator): Object;
}
interface FunctionType extends Type
{
function hasBoundThis(): Boolean;
function returnType(): Type;
function argTypes(): TypeIterator;
function construct(typeArgs: TypeIterator, valArgs: ValueIterator): *;
function apply(typeArgs: TypeIterator, thisArg: Object?, valArgs: ValueIterator): *;
}
Implementations may choose to provide further extensions to these interfaces, to provide richer reflective capabilities. Clients wishing to use extended meta-object interfaces can perform runtime downcasts on the basic meta-objects provided by this spec.
The dynamic values of the built-in classes are instances of ClassType.
Object is ClassType String is ClassType
The dynamic values of structural types are instances of ObjectType, FunctionType, UnionType, or ArrayType.
(type {x:int}) is ObjectType (type function(int):*) is FunctionType (type (int,String)) is UnionType (type [int]) is ArrayType
Since the reflective meta-type API is given as interfaces, then the runtime value of each of these meta-types is an InterfaceType.
Type is InterfaceType NominalType is InterfaceType ClassType is InterfaceType FunctionType is InterfaceType UnionType is InterfaceType ArrayType is InterfaceType
Looks like this follows the principles in http://bracha.org/mirrors.pdf.
— Brendan Eich 2007/01/04 14:36