=pod

=head1 Perl 6 Meta-Model

This document will attempt to codify the perl 6 meta-model. It is very
much still a work in progress and it's contents may change by the minute
at times.

=head1 The Perl 6 Object environment

The Perl 6 object environment will be a multi-layered environment which 
might look something like this:

 +-{Instance}-+ +---{Type}--+ +--{Class}--+ +--{MetaClass}--+
 |            | |           | |           | |               |
 |   ------   | |   -----   | |  -------  | |  -----------  |
 |  ( $foo )------>( Foo )----->( Class )---->( MetaClass ) |
 |   ------   | |   -----   | |  -------  | |  -----------  |
 |            | |::Foo      | |::Foo.meta | |::Foo.meta.meta|
 |            | |$foo.ref   | |           | |               |
 +------------+ +-----------+ +-----------+ +---------------+

The following describes some of the details of this leveled
environment.

This document does not touch on the intricacies of the Class model
(roles, types, sub-types, classes, etc) - these are all contained in
the Class level and, for the sake of this document, are treated as an
opaque "Class".

=over 4

=item B<each "level" is independant of the levels above and below it>

Relationships such as "is a", "does a", etc only make sense within a
particular level of the object system.  So, for example, it does not
make sense to describe all of these objects as descending from some
I<über>-Object class.  Rules and principles that apply on one level do
not necessarily transfer to the levels below.

=item B<each "level" looks like Objects from Perl>

Despite this inherant heterogeneity of each level, they all look like
Objects from Perl.  They are described and accessed in exactly the
same way, and can even share type definitions and refer to each other,
to some extent.  So, they all C<.does(Object)>, this is a definition.

The below table attempts to summarise the implications of these two
points as code.

In the below table,

   $foo = MyClass.new
   $type = ::MyClass;
   $meta = MyClass.meta;
   $meta_meta = MyClass.meta.meta;

 Topic:          $foo       $type      $meta     $meta_meta
 .ref          ::MyClass   ::Type     ::Class  ::Meta::Class
 .isa(Object)      true     false      false      false
 .does(Object)     true     true       true       true
 .isa(MyClass)     true     true       false      false
 .does(MyClass)    true     true       false      false
 .isa(Class)       false    false      true       false
 .does(Class)      false    true       true       true
 .isa(Type)        false    true       true?      true?
 .does(Type)       false    true       true       true
 .isa(Meta::Class) false    false      false      true
 .does(Meta::Class)false    false      false      true
 .meta             dies     $meta    $meta_meta   dies(*)

(*) - this might return magic proxy objects that go on forever, but
this is not required for core operation.

Even the above is in an ideal situation; it might be that with some
weird MetaModels, you simply don't get those guarantees.  However,
such situations are probably a bit 'obstruese' so won't be mentioned
further.

=back

=head2 Occupants of the Perl 6 object environment

=over 4

=item B<Every C<Object> is an instance of a C<Type>>

These are the occupants of our environment B<O>.  Every
noted C<Object> has exactly one uniquely associated entity
called a C<Type>.

99% of code will be using C<Objects> for absolutely
everything.

=item B<Every C<Type> is defined by a C<Class>>

C<Type> objects are normally identified by a leading C<::>, however if
a type is global or is in scope, the C<::> prefix may be safely
dropped.

C<Type> objects always have a C<Class> object, which may or may not be
named.  This object is available via C<.meta()>.

C<Type> objects respond to C<.isa()>, C<.does()>, C<.can()>, etc
methods by querying their associated C<.meta()> object with
C<.classCan()>, etc method calls, quite possibly caching the results
for faster method dispatch.

=item B<Every C<::SomeType.meta> is a C<Class>>

The objects are what would normally be described as your program's
I<Model>; ie, objects that are I<Classes> (or I<Roles>, etc) will be
called "Dog", "Tree", etc.

When you write:

  class Dog {
  }

You are actually doing something like this;

  Class.new(name => Dog).apply;

This is because the term C<Class> actually refers to a C<Meta::Class>,
not a C<Class>.  There is nothing special about the term C<Class> that
makes it so, other than it was defined so.  If we had chosen the term
C<Qualifarniciferate> to refer to instances of C<Meta::Class>es, then
the above would simply create an object of class (sorry,
Qualifarniciferate) C<Class>.

=item B<C<Class> objects are instances of the "Class" C<Meta::Class>>

C<Class> objects are presented to Perl in much the same manner as
instances of some C<Class> called C<Meta::Class> might be.  This might
fool you into thinking that they are also instances of some C<Class>,
however in truth they are only ever instances of C<Meta::Class>
objects.

Instances of C<Meta::Class> objects are what would normally be
described as your B<language> I<Model>, or program I<Meta-Model>.
These will be called "Class", "Role", etc.

It is these objects that implement methods like C<.isa>, C<.does>,
etc.  They will provide proxy methods in the C<Type> objects that they
produce, that when compiled will produce the desired behaviour.

If you are performing run-time class creation without C<eval()>, it is
I<these> objects that you need to call methods like C<.addMethod()>
to.  They may or may not be `compiled' to run-time ::Type objects
immediately after any change, however such behaviour may be considered
undefined.

=item B<C<Meta::Class> are instances of I<Meta::Meta::Class>es>

The C<Meta::Meta::Class> objects define the structure of the
C<Meta::Class> objects.

If you are performing run-time trait specification without C<eval()>,
such as by adding I<Class Traits>, I<Role Traits>, and other language
object traits, you are modifying objects on this level.  New
C<Meta::Property> objects will be attached to the relevant
C<Meta::Class> objects.  Hence, when you define a new trait, you are
not modifying the program model, you are modifying the language model.

On the other hand, when you assign a trait to a new variable, you are
creating a new type that has a new anonymous class which is the old
class with the extra trait property set, so that requires no
modifications on this level.

=item B<C<Meta::Meta::Class> are instances of the interpreter>

In theory, we could extend this Meta::Meta relationship to any level.
However, it simply does not make much sense to deal with these objects
directly; altering them is even more confusing.  They might be Haskell
definitions in the case of C<pugs>, or perhaps in a Pure Perl
Interpreter they will actually be real C<Object>s; but you will not
see the definition of C<Meta::Meta::Meta::Class> in this module; in a
sense, Perl 6 classes are being used as an underlying
I<Meta::Meta::Model>.

=back

=head1 AUTHORS

Sam Vilain E<lt>samv@cpan.orgE<gt>

Stevan Little E<lt>stevan@iinteractive.comE<gt>

=cut
